Con trỏ trong C giúp cho việc thực hiện chương trình C trở nên thật dễ dàng và đơn giản. Một số nhiệm vụ lập trình C được thực hiện dễ dàng hơn với con trỏ và các tác vụ khác, chẳng hạn như cấp phát bộ nhớ động, việc này sẽ không thể thực hiện được mà không sử dụng con trỏ. Vì vậy, kiến thức về con trỏ là một trong những yếu tố mà mỗi lập trình viên đều không thể bỏ qua Hãy bắt đầu học chúng theo các bước đơn giản và dễ dàng dưới đây.
Như bạn đã biết, mỗi biến sẽ có một vị trí bộ nhớ và vị trí bộ nhớ đó đều có địa chỉ của nó được xác định có thể được truy cập bằng toán tử & (&), biểu thị địa chỉ trong bộ nhớ. Hãy xem ví dụ sau:
#include
int main () {
int var1;
char var2[10];
printf("Address of var1 variable: %x\n", &var1 );
printf("Address of var2 variable: %x\n", &var2 );
return 0;
}
Khi mã trên được biên dịch và thực hiện, nó tạo ra kết quả sau:
Address of var1 variable: bff5a400
Address of var2 variable: bff5a3f6
Con trỏ là một biến có giá trị, là địa chỉ của một biến khác, tức là địa chỉ trực tiếp của vị trí bộ nhớ. Giống như bất kỳ biến hoặc hằng số nào, bạn phải khai báo một con trỏ trước khi sử dụng nó để lưu trữ bất kỳ địa chỉ biến. Hình thức chung của một khai báo biến con trỏ là:
type *var-name;
Ở đây, type là kiểu cơ sở của con trỏ, nó là một kiểu dữ liệu C hợp lệ và var-name là tên của biến con trỏ. Dấu sao * được sử dụng để khai báo một con trỏ là dấu hoa thị được sử dụng cho phép nhân. Tuy nhiên, trong câu lệnh này, dấu hoa thị đang được sử dụng để chỉ định một biến làm con trỏ. Hãy xem một số khai báo con trỏ hợp lệ:
int *ip; /* pointer to an integer */
double *dp; /* pointer to a double */
float *fp; /* pointer to a float */
char *ch /* pointer to a character */
Kiểu dữ liệu thực tế của tất cả các con trỏ, cho dù là số nguyên, dấu phẩy, ký tự hay kiểu khác đều phải giống nhau. Một số thập lục phân dài đại diện cho một địa chỉ bộ nhớ. Sự khác biệt duy nhất giữa các con trỏ của các kiểu dữ liệu khác là kiểu dữ liệu của biến hoặc hằng số mà con trỏ trỏ tới.
Có một vài hoạt động quan trọng, mà bạn sẽ cần làm với sự trợ giúp của con trỏ một cách thường xuyên.
Xác định một biến con trỏ.
Gán địa chỉ của một biến cho một con trỏ
Truy cập vào giá trị tại địa chỉ có sẵn trong biến con trỏ. Điều này được thực hiện bằng cách sử dụng toán tử unary * trả về giá trị của biến nằm tại địa chỉ được chỉ định bởi toán hạng của nó.
Ví dụ:
#include
int main () {
int var = 20; /* actual variable declaration */
int *ip; /* pointer variable declaration */
ip = &var; /* store address of var in pointer variable*/
printf("Address of var variable: %x\n", &var );
/* address stored in pointer variable */
printf("Address stored in ip variable: %x\n", ip );
/* access the value using the pointer */
printf("Value of *ip variable: %d\n", *ip );
return 0;
}
Khi mã trên được biên dịch và thực hiện, nó tạo ra kết quả sau:
Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20
Điều này được thực hiện tại thời điểm khai báo biến. Một con trỏ được gán NULL được gọi là một con trỏ null. Con trỏ NULL là một hằng số với một giá trị bằng không được định nghĩa trong một số thư viện chuẩn. Xem xét chương trình sau:
#include
int main () {
int *ptr = NULL;
printf("The value of ptr is : %x\n", ptr );
return 0;
}
Khi mã trên được biên dịch và thực hiện, nó tạo ra kết quả sau:
The value of ptr is 0
Trong hầu hết các hệ điều hành, các chương trình không được phép truy cập bộ nhớ tại địa chỉ 0 vì bộ nhớ đó được dành riêng bởi hệ điều hành. Tuy nhiên, địa chỉ bộ nhớ 0 có ý nghĩa đặc biệt:nó báo hiệu con trỏ không có ý định trỏ tới vị trí bộ nhớ có thể truy cập. Nhưng theo quy ước, nếu một con trỏ chứa giá trị null (không), nó được giả định là trỏ đến không có gì.
Để kiểm tra một con trỏ null, bạn có thể sử dụng câu lệnh if nếu như sau:
if(ptr) /* succeeds if p is not null */
if(!ptr) /* succeeds if p is null */
Các khái niệm con trỏ quan trọng sau đây bất kỳ lập trình viên C nào cũng cần nắm được:
Con trỏ số học: Có bốn toán tử số học có thể được sử dụng trong con trỏ: ++, -, +, -
Con trỏ mảng: Bạn có thể định nghĩa các mảng để giữ một số con trỏ.
Con trỏ đến con trỏ: C cho phép bạn có con trỏ trên một con trỏ,….
Chuyển con trỏ đến hàm trong C: Việc chuyển đối số bằng tham chiếu hoặc theo địa chỉ cho phép đối số đã truyền được thay đổi trong hàm gọi bằng hàm.
Trả về con trỏ từ các hàm trong C: C cho phép một hàm trả về một con trỏ tới biến cục bộ, biến tĩnh và bộ nhớ được cấp phát động.
Tài liệu lập trình C liên quan khác bạn nên xem: