Monday, April 20, 2015

Con trỏ đa cấp - Mảng hai chiều [Pointers to pointers - Two dimention array]

Con trỏ đa cấp là gì?

Để các bài viết thống nhất với nhau và tiện trong việc sử dụng câu chữ tôi sẽ gọi là "Pointer đa cấp" thay vì "Con trỏ đa cấp".

Chúng ta đã biết rằng pointer đơn giản chỉ là một phiên bản mở rộng của variable, do đó, một pointer cũng hoàn toàn có thể trỏ vào một pointer khác, một pointer như thế thì được gọi là một pointer đa cấp. Pointer là một trường hợp của Pointer đa cấp có tên là Pointer một cấp.

Khái niệm pointer đa cấp (pointers to pointers) có lẽ khá xa lạ với nhiều bạn sinh viên, không phải vì nó không hữu ích mà vì qui mô các bài toán ở giảng đường ít khi cần tới nó. Pointer đa cấp là một công cụ tuyệt vời giúp bạn giải quyết các vấn đề thực tế liên quan đến mảng hai chiều một cách mềm dẻo và hiệu quả.

Khai báo Pointer đa cấp

Việc sử dụng con trỏ đa cấp là tương tự nhau, do đó trong bài này tôi sẽ chỉ đề cập đến pointer 2 cấp (pointer to a pointer). Để khai báo một pointer hai cấp bạn phải thêm hai giấu '*' trước tên của nó.
VD1: int **p_p_parameter;

Sử dụng Pointer đa cấp

Để dễ hiểu nhất, chúng ta sẽ phân tích cách sử dụng pointer hai cấp thông qua ví dụ sau.
VD2:
Khai báo variable parameter, pointer p_parameter và poiter hai cấp p_p_prameter.
int parameter[100];       // variable
int *p_parameter;         // pointer một cấp
int **p_p_parameter;   // pointer hai cấp

Pointer hai cấp không thể trỏ trực tiếp tới variable như pointer được
p_p_parameter = &parameter;  // lỗi
p_parameter = &parameter;  // không lỗi

Pointer hai cấp quản lý variable thông qua pointer một cấp làm trung gian
p_parameter = &parameter;      // pointer trỏ tới variable
p_p_parameter = &p_parameter;  // pointer hai cấp trỏ tới pointer một cấp
Sau hai câu lệnh này p_p_parameter đã trỏ tới vùng nhớ của parameter.

[ thêm hinh vẽ mô tả bộ nhớ]

p_p_parameter truy cuất mảng parameter[100] gián tiếp qua pointer p_parameter 
int parameter[100];       // variable
int *p_parameter;         // pointer một cấp
int **p_p_parameter;   // pointer hai cấp
parameter[0] = 101;
parameter[1] = 1001;
p_parameter = &parameter;      
p_p_parameter = &p_parameter; 
printf("parameter[0]=%d\n",**p_p_parameter );
p_parameter++;                               // pointer 1 cấp truy xuất địa chỉ mới của variable
printf("parameter[1]=%d\n",**p_p_parameter);  
kết quả in ra sẽ là:
parameter[0] = 101;
parameter[1] = 1001;

Ví dụ trên chỉ là mô hình đơn giản để bạn hiểu về pointer hai cấp, trong hầu hết các trường hợp thực tế người ta chỉ ứng dụng pointer hai cấp trong các bài toán liên quan mảng hai chiều.

Cấp phát bộ nhớ cho pointer hai cấp 

Bộ nhớ được cấp phát cho
B1: cấp phát ô nhớ kiểu pointer
p_p_parameter = new int*[5];
tức là bước này sẽ cấp phát các ô nhớ, nhưng các ô nhớ đó được định nghĩa như các pointer chứ không phải là variable vì pointer 2 cấp chỉ có thể trỏ tới pointer 1 cấp
B2: cấp phát ô nhớ variable
các ô nhớ pointer có thể trỏ tới các ô nhớ variable 
p_p_prameter = new int;



chung ta thay rang pointer 2 cap quan ly 1 vung nho giong nhu 1 mang hai chieu, day chinh la ung dung chinh cua pointer 2 cap de tra loi cau hoi 1 tren.

Giải phóng bộ nhớ pointer hai cấp

lam sao để free con trỏ 2 cấp
free con trỏ 1 cấp trước
free(p_p_parameter[i]);
free(p_p_parameter);

So sánh pointer hai cấp với mảng hai chiều

Vấn đề đặt ra là hoàn toàn có thể khai báo 1 mảng hai chiều nhanh chóng để sử dụng, vậy lúc nào dùng pointer 2 cấp lúc nào khai báo trực tiếp:

-khi chưa biết trước kích thước của mảng và cần hiệu quả trong sử dụng bộ nhớ.


No comments:

Post a Comment