Monday, April 27, 2015

1. Pointer
Pointer là một biến dùng để chứa địa chỉ của một biến khác. Mỗi khi khai báo một biến thì nó sẽ được cấp phát một vùng nhớ, biến pointer cũng như vậy, chỉ có khác là vùng nhớ của biến thường sẽ chứa các giá trị kiểu như 1, 2, 3.14, ... còn vùng nhớ của pointer lại chứa giá trị là địa chỉ của biến mà nó trỏ đến, kiểu như 0x0001, 0x0004, 0x0008, ... Pointer sẽ trỏ đến biến thường có cùng type với nó. Về mục đích sử dụng, pointer được ứng dụng trong việc quản lý và tối ưu bộ nhớ (Memory Management), linh hoạt trong việc điều khiển chương trình, ... các vấn đề này sẽ được trình bày dần dần trong các bài viết sau.

Khai báo:

 type *p;  

Phép toán lấy địa chỉ: &
 int *p = NULL;   
 int a = 1;   
 p = &a; /* p tro den a */ 

Lấy giá trị của vùng nhớ mà pointer trỏ đến: *
 printf("Gia tri vung nho ma p tro den: %d \n", *p);  

Ex:
pointer.c
 #include <stdio.h>  
 #include <stdlib.h>  
 int main()  
 {  
   int *p = NULL;  
   int a = 1;  
   int b = 2; 
 
   p = &a;  
   printf("Gia tri cua p: %x \n", p);  
   printf("Gia tri vung nho ma p tro den: %d \n", *p);
  
   p = &b;  
   printf("Gia tri cua p: %x \n", p);  
   printf("Gia tri vung nho ma p tro den: %d \n", *p);  

   p = NULL;  
   
   return 0;  
 }  

Hình dưới mô tả cho chương trình trên

Note: Các địa chỉ từ 0x00000000, ..., 0x00000007 trong hình chỉ để mô tả cho dễ hiểu, còn khi chạy thực tế thì sẽ nhận được các địa chỉ khác, và mỗi lần chạy lại được các địa chỉ khác nhau.

2. Pointer to Pointer
Con trỏ trỏ đến con trỏ là biến dùng để chứa địa chỉ của một con trỏ khác. Pointer-to-Pointer thường được dùng để đưa một con trỏ vào trong một hàm để thực hiện các thao tác liên quan đến cấp phát hay giải phóng bộ nhớ (sẽ được đề cập sau ở phần Functions).

Khai báo:
 type **p;  

Phép toán lấy địa chỉ và giá trị tương tự như pointer.

Ex:
pointer-to-pointer.c
 #include <stdio.h>  
 #include <stdlib.h>  
 int main()  
 {  
   int **pp = NULL; /* pointer to pointer */  
   int *p = NULL; /* pointer */  
   int a = 1; 
 
   pp = &p;  
   printf("Gia tri cua pp: %x \n", pp); /* dia chi cua p */  
   printf("Gia tri vung nho ma pp tro den: %d \n", *pp); /* NULL(0) */ 
 
   p = &a;  
   printf("Gia tri cua pp: %x \n", pp); /* dia chi cua p */  
   printf("Gia tri vung nho ma pp tro den: %d \n", *pp); /* dia chi cua a */  
   return 0;  
 }  

Hình dưới mô tả cho chương trình trên

3. Void Pointer: *void 
Con trỏ void còn được gọi với tên General Purpose Pointer - Con trỏ mục đích chung. Thường thì ta phải khai báo con trỏ char để trỏ đến biến char, con trỏ int để trỏ đến biến int, con trỏ float để trỏ đến biến float, ...thay vào đó ta chỉ cần khai báo một con trỏ void là có thể trỏ đến tất cả các kiểu dữ liệu trên.

Note: Khi muốn lấy giá trị của biến mà void pointer trỏ đến thì cần phải ép kiểu lại với kiểu dữ liệu của biến bị trỏ.

Ex:
void-pointer.c
 #include <stdio.h>  
 #include <stdlib.h>  

 struct Something  
 {  
   int nValue;  
   float fValue;  
 };  

 int main()  
 {  
   int nValue;  
   float fValue;  
   struct Something sValue;  
   void *pVoid = NULL; 
 
   nValue = 1;  
   fValue = 3.14f;  
   sValue.nValue = 2;  
   sValue.fValue = 2.7f;  

   pVoid = &nValue; // valid  
   printf("nValue = %d \n", *((int*)pVoid)); 
 
   pVoid = &fValue; // valid  
   printf("fValue = %f \n", *((float*)pVoid));
  
   pVoid = &sValue; // valid  
   printf("sValue.nValue = %d \n", ((struct Something*)pVoid)->nValue);  
   printf("sValue.fValue = %f \n", ((struct Something*)pVoid)->fValue);  

   return 0;  
 }  

Compile & Execute
 $ gcc void-pointer.c   
 $ ./a.out   
 nValue = 1   
 fValue = 3.140000   
 sValue.nValue = 2   
 sValue.fValue = 2.700000   

4. Function Pointer
 Con trỏ không chỉ trỏ đến các kiểu dữ liệu mà nó còn được dùng để trỏ đến các hàm, khi đó gọi là con trỏ hàm - function pointer. Về bản chất, khi một hàm được khai báo thì nó cũng sẽ được cấp phát một vùng nhớ, vì thế con trỏ mới trỏ đến được.
Note: Function Pointer thường được dùng để lập trình C theo phong cách hướng đối tượng, khi đó function pointer sẽ là một field trong struct (sẽ được đề cập ở phần Struct).

Khai báo:
 type (*funcPointer)(type1, type2, ..., typen) = NULL;  

Ex:
function-pointer.c
 #include <stdio.h>  
 /* Function Pointer */  
 int (*pt2Function)(float, char, char) = NULL; // C  
 /* Test function */  
 int DoIt (float a, char b, char c) {  
   printf("DoIt\n");  
   return a+b+c;  
 }  
 int DoMore(float a, char b, char c){  
   printf("DoMore\n");  
   return a-b+c;  
 }  
 int main()  
 {  
   int ret;  
   pt2Function = DoIt; // short form  
   ret = pt2Function(1, 2, 3);  
   printf("ret value: %d \n", ret);  
   pt2Function = &DoMore; // correct assignment using address operator  
   ret = pt2Function(1, 2, 3);  
   printf("ret value: %d \n", ret);  
   return 0;  
 }  

Compile & Execute:
 $ gcc function-pointer.c   
 $ ./a.out   
 DoIt  
 ret value: 6   
 DoMore  
 ret value: 2   


Leave a Reply

Subscribe to Posts | Subscribe to Comments

- Copyright © Lập trình hệ thống nhúng Linux . Powered by Luong Duy Ninh -