Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Lập Trình C

Con trỏ (Pointer) và Tham chiếu (Reference) trong C

Lưu ý quan trọng

C không có "Reference" (tham chiếu) như C++. Bài viết gốc nhầm lẫn khái niệm. Trong C chỉ có Con trỏ (Pointer) và Truyền tham chiếu bằng con trỏ.

Con trỏ (Pointer) trong C

Con trỏ là biến lưu trữ địa chỉ bộ nhớ của biến khác.

Khai báo

int *p;      // Con trỏ tới int
float *fp;   // Con trỏ tới float
char *cp;    // Con trỏ tới char

Toán tử quan trọng

Toán tử Tên Chức năng
&Address-ofLấy địa chỉ biến
*DereferenceTruy cập giá trị tại địa chỉ

Chương trình minh họa

#include <stdio.h>

int main() {
    int a = 10, b = 20;
    int *p;  // Khai báo con trỏ int
    
    printf("Dia chi a: %p\n", (void*)&a);
    printf("Dia chi b: %p\n", (void*)&b);
    
    // p trỏ đến a
    p = &a;
    printf("\np tro den a:\n");
    printf("Gia tri a: %d\n", a);
    printf("Gia tri *p: %d\n", *p);  // Giá trị tại địa chỉ p
    printf("Dia chi p (gia tri cua p): %p\n", (void*)p);
    
    // p trỏ đến b
    p = &b;
    printf("\np tro den b:\n");
    printf("Gia tri b: %d\n", b);
    printf("Gia tri *p: %d\n", *p);
    printf("Dia chi p: %p\n", (void*)p);
    
    // Thay đổi giá trị qua con trỏ
    *p = 99;
    printf("\nSau khi *p = 99:\n");
    printf("b = %d\n", b);  // b đã thay thành 99
    
    return 0;
}

Kết quả

Dia chi a: 0x7ffc1234
Dia chi b: 0x7ffc1238

p tro den a:
Gia tri a: 10
Gia tri *p: 10
Dia chi p: 0x7ffc1234

p tro den b:
Gia tri b: 20
Gia tri *p: 20
Dia chi p: 0x7ffc1238

Sau khi *p = 99:
b = 99

Truyền tham chiếu (Pass by Reference) trong C

C chỉ có Truyền giá trị (Pass by Value). Để mô phỏng truyền tham chiếu, ta truyền địa chỉ (con trỏ).

Truyền giá trị (Không thay đổi gốc)

void doiGiaTri(int x) {
    x = 20;  // Chỉ thay đổi bản sao
}

int main() {
    int a = 10;
    doiGiaTri(a);
    printf("%d\n", a);  // Vẫn là 10
}

Truyền địa chỉ (Thay đổi được gốc)

void doiGiaTri(int *x) {
    *x = 20;  // Thay đổi giá trị tại địa chỉ
}

int main() {
    int a = 10;
    doiGiaTri(&a);  // Truyền địa chỉ
    printf("%d\n", a);  // Thành 20
}

So sánh Pointer vs Reference (C++)

Đặc điểm Pointer (C/C++) Reference (Chỉ C++)
Cú phápint *p = &a;int &r = a;
Có thể NULLCóKhông (luôn tham chiếu hợp lệ)
Thay đổi đối tượng trỏĐược (p = &b)Không (gán một lần)
Truy cập giá trị*pr (tự động dereference)
Kích thước4/8 bytesCùng kích thước đối tượng

Các loại con trỏ phổ biến

  • Con trỏ NULL: int *p = NULL; hoặc int *p = 0;
  • Con trỏ void: void *vp; - trỏ đến bất kỳ kiểu nào
  • Con trỏ hằng: const int *p (giá trị không đổi) vs int *const p (địa chỉ không đổi)
  • Con trỏ hàm: int (*func)(int, int);
  • Con trỏ cấp 2: int **pp; - trỏ đến con trỏ

Ứng dụng chính của con trỏ

  1. Cấp phát bộ nhớ động (malloc, free)
  2. Truyền mảng/hàm vào hàm
  3. Cấu trúc dữ liệu: linked list, tree, graph
  4. Thao tác chuỗi, file, phần cứng
  5. Tối ưu hiệu năng (tránh copy dữ liệu lớn)

Nắm vững con trỏ là chìa khóa thành thạo C. Hãy tập luyện nhiều với &, *, mảng-con trỏ, và cấp phát động.