Con trỏ (Pointer) trong C/C++ (Part 2) | Có thể bạn chưa biết!

Đăng bởi: Admin | Lượt xem: 1653 | Chuyên mục: C/C++

Trong phần trước chúng ta đã tìm hiểu về một số vấn đề cơ bản của con trỏ (Pointer) trong C/C++. Trong phần này chúng ta tiếp tục đi sâu hơn về các biến thể và ứng dụng của nó.


Mảng các con trỏ trong C++

Trước khi chúng ta hiểu về khái niệm mảng các con trỏ, chúng ta xem xét ví dụ sau, mà sử dụng một mảng gồm 3 số integer:

#include <iostream>
 
using namespace std;
const int MAX = 3;
 
int main ()
{
   int  var[MAX] = {10, 100, 200};
 
   for (int i = 0; i < MAX; i++)
   {
      cout << "Gia tri cua var[" << i << "] = ";
      cout << var[i] << endl;
   }
   return 0;
}

Khi code trên được biên dịch và thực thi, nó cho kết quả sau:

Gia tri cua var[0] = 10
Gia tri cua var[1] = 100
Gia tri cua var[2] = 200

Có một tình huống khi chúng ta muốn duy trì một mảng, mà có thể lưu giữ các con trỏ tới một kiểu dữ liệu int hoặc char hoặc bất kỳ kiểu nào khác. Sau đây là khai báo một mảng của các con trỏ tới một integer:

int *contro[MAX];

 Nó khai báo contro như là một mảng các con trỏ MAX kiểu integer. Vì thế, mỗi phần tử trong contro, bây giờ giữ một con trỏ tới một giá trị int. Ví dụ sau sử dụng 3 số integer, mà sẽ được lưu giữ trong một mảng các con trỏ như sau:

#include <iostream>
 
using namespace std;
const int MAX = 3;
 
int main ()
{
   int  var[MAX] = {10, 100, 200};
   int *contro[MAX];
 
   for (int i = 0; i < MAX; i++)
   {
      contro[i] = &var[i]; // gan dia chi cua so nguyen.
   }
   for (int i = 0; i < MAX; i++)
   {
      cout << "Gia tri cua var[" << i << "] = ";
      cout << *contro[i] << endl;
   }
   return 0;
}

Khi code trên được biên dịch và thực thi, nó cho kết quả sau:

Gia tri cua var[0] = 10
Gia tri cua var[1] = 100
Gia tri cua var[2] = 200

Bạn có thể sử dụng một mảng các con trỏ tới ký tự để lưu giữ một danh sách các chuỗi như sau:

#include <iostream>
 
using namespace std;
const int MAX = 4;
 
int main ()
{
   char *tensv[MAX] = {
                   "Nguyen Thanh Tung",
                   "Tran Minh Chinh",
                   "Ho Ngoc Ha",
                   "Hoang Minh Hang",
   };

   for (int i = 0; i < MAX; i++)
   {
      cout << "Gia tri cua tensv[" << i << "] = ";
      cout << tensv[i] << endl;
   }
   return 0;
}

Chạy chương trình C++ trên sẽ cho kết quả như hình sau:

Mảng Con trỏ trong C++ 

 

Con trỏ tới con trỏ trong C++

Một con trỏ tới một con trỏ là một form không định hướng hoặc một chuỗi con trỏ. Thông thường, một con trỏ chứa địa chỉ của một biến. Khi chúng ta định nghĩa một con trỏ tới một con trỏ, con trỏ đầu tiên chứa địa chỉ của con trỏ thứ hai, mà trỏ tới vị trí mà chứa giá trị thực sự như hiển thị trong sơ đồ dưới đây:

Con trỏ tới con trỏ trong C++

Một biến, mà là một con trỏ tới một con trỏ, phải được khai báo. Điều này được thực hiện bởi việc đặt một dấu sao (*) ở trước tên của nó. Ví dụ, sau đây là khai báo một con trỏ tới một con trỏ trong kiểu int:

int **var;

Khi một giá trị mục tiêu được trỏ không định hướng bởi một con trỏ tới một con trỏ, truy cập giá trị đó yêu cầu rằng toán tử dấu sao được áp dụng hai lần, như dưới ví dụ:

#include <iostream>
 
using namespace std;
 
int main ()
{
   int  var;
   int  *ptr;
   int  **pptr;

   var = 125;

   // lay dia chi cua var
   ptr = &var;

   // lay dia chi cua ptr boi su dung dia chi cua toan tu &
   pptr = &ptr;

   // Lay gia tri boi su dung pptr
   cout << "Gia tri cua var la: " << var << endl;
   cout << "Gia tri tai *ptr la: " << *ptr << endl;
   cout << "Gia tri tai **pptr la: " << **pptr << endl;

   return 0;
}

Chạy chương trình C++ trên sẽ cho kết quả như hình sau:

Con trỏ trỏ tới Con trỏ trong C++

 

Truyền con trỏ tới hàm trong C++ 

C++ cho phép bạn truyền một con trỏ tới một hàm. Để làm điều này, đơn giản bạn chỉ cần khai báo tham số hàm như ở dạng một kiểu con trỏ.

Ở ví dụ đơn giản dưới đây, chúng ta truyền một con trỏ unsigned long tới một hàm và thay đổi giá trị bên trong hàm, mà phản chiếu trở lại trong khi gọi hàm:

#include <iostream>
#include <ctime>
 
using namespace std;
void laySoGiay(unsigned long *par);

int main ()
{
   unsigned long sogiay;


   laySoGiay( &sogiay );

   // in gia tri
   cout << "So giay la: " << sogiay << endl;

   return 0;
}

void laySoGiay(unsigned long *par)
{
   // Lay so giay hien tai
   *par = time( NULL );
   return;
}

Chạy chương trình C++ trên sẽ cho kết quả như hình sau:

Truyền con trỏ tới hàm trong C++

Hàm, mà có thể chấp nhận một con trỏ, cũng có thể chấp nhận một mảng như ví dụ sau:

#include <iostream>
using namespace std;
 
// khai bao ham:
double giaTriTB(int *arr, int size);
 
int main ()
{
   // mot mang so nguyen co 5 phan tu.
   int doanhSoBH[5] = {122, 35, 27, 235, 60};
   double trungbinh;
 
   // truyen con tro toi mang duoi dang mot tham so.
   trungbinh = giaTriTB( doanhSoBH, 5 ) ;
 
   // hien thi ket qua 
   cout << "Gia tri trung binh la: " << trungbinh << endl; 
    
   return 0;
}

double giaTriTB(int *arr, int size)
{
  int    i, sum = 0;       
  double trungbinh;          
 
  for (i = 0; i < size; ++i)
  {
    sum += arr[i];
   }
 
  trungbinh = double(sum) / size;
 
  return trungbinh;
}

Khi chương trình C++ trên được biên dịch và thực thi, nó cho kết quả sau:

Gia tri trung binh la: 95.8

 

Trả về con trỏ từ hàm trong C++ 

Như chúng ta đã thấy cách C++ cho phép trả về một mảng từ một hàm, tương tự như vậy, C++ cho phép bạn trả về một con trỏ từ một hàm. Để làm điều này, bạn phải khai báo một hàm trả về một con trỏ như sau:

int * tenHam()
{
.
.
.
}

Điều thứ hai cần ghi nhớ là, nó không là ý kiến tốt để trả về địa chỉ của một biến cục bộ tới ngoại vi của một hàm, vì thế bạn sẽ phải định nghĩa biến cục bộ như là biến static.

Bây giờ, giả sử hàm sau sẽ tạo 10 số ngẫu nhiên và trả về chúng bởi sử dụng một tên mảng mà biểu diễn một con trỏ, ví dụ, địa chỉ đầu tiên của phần tử mảng đầu tiên.

#include <iostream>
#include <ctime>
#include <stdlib.h>   
using namespace std;
 
// phan dinh nghia ham de tao va tra ve cac so ngau nhien.
int * soNgauNhien( )
{
  static int  r[10];
 
 
  srand( (unsigned)time( NULL ) );
  for (int i = 0; i < 10; ++i)
  {
    r[i] = rand();
    cout << r[i] << endl;
  }
 
  return r;
}
 
// ham main de goi phan dinh nghia ham tren.
int main ()
{
   // mot con tro tro toi mot so nguyen.
   int *p;
 
   p = soNgauNhien();
   for ( int i = 0; i < 10; i++ )
   {
       cout << "Gia tri cua *(p + " << i << ") : ";
       cout << *(p + i) << endl;
   }
 
   return 0;
}

 Chạy chương trình C++ trên sẽ cho kết quả như hình sau:

Mảng Con trỏ trong C++

Loạt bài viết về con trỏ (Pointer) trong C/C++ đến đây là kết thúc. Mong các bạn tiếp tục theo dõi các bài viết hay và bổ ích trên trang vncoder.vn.

Cảm ơn và quyết thắng!!!

vncoder logo

Theo dõi VnCoder trên Facebook, để cập nhật những bài viết, tin tức và khoá học mới nhất!



Khóa học liên quan

Khóa học: C/C++

Sử dụng thư viện chuẩn STL cho C/C++
Số bài học:
Lượt xem: 22584
Đăng bởi: Admin
Chuyên mục: C/C++

Học lập trình C cơ bản
Số bài học:
Lượt xem: 18587
Đăng bởi: Admin
Chuyên mục: C/C++