Con trỏ là biến lưu trữ địa chỉ của biến khác.
Đặc điểm
- Con trỏ tiết kiệm không gian bộ nhớ.
- Thực thi nhanh do truy cập trực tiếp bộ nhớ.
- Cấp phát/giải phóng bộ nhớ động hiệu quả.
- Dùng với cấu trúc dữ liệu.
Khai báo, khởi tạo, truy cập con trỏ
Xét: int qty = 179;

Khai báo con trỏ
int *p;
Khởi tạo con trỏ
Toán tử & dùng để khởi tạo.
int qty = 175; int *p; p = &qty;

Truy cập biến qua con trỏ
Dùng toán tử * (gián tiếp).

'*' coi như giá trị tại địa chỉ.
Hai câu lệnh tương đương:
p = &qty; n = *p; n = qty
Con trỏ và mảng một chiều
- Trình biên dịch cấp phát bộ nhớ liên tục cho tất cả phần tử mảng.
- Địa chỉ cơ sở = địa chỉ phần tử đầu (chỉ số 0). Ví dụ: int a[5] = {10, 20, 30, 40, 50};
Các phần tử
5 phần tử lưu trữ như sau:

- Nếu 'p' khai báo là con trỏ nguyên, mảng 'a' được trỏ bởi: p = a; (hoặc) p = &a[0];
- Mỗi giá trị 'a' truy cập bằng p++ để chuyển phần tử. Khi con trỏ tăng, giá trị tăng theo kích thước kiểu dữ liệu trỏ tới. Độ dài này gọi "hệ số tỷ lệ" (scale factor).
- Mối quan hệ p và a:
P = &a[0] = 1000 P+1 = &a[1] = 1004 P+2 = &a[2] = 1008 P+3 = &a[3] = 1012 P+4 = &a[4] = 1016
- Địa chỉ phần tử tính bằng chỉ số và scale factor. Ví dụ:
Địa chỉ a[3] = địa chỉ cơ sở + (3 * scale factor int) = 1000 + (3*4) = 1012
- Con trỏ dùng để truy cập phần tử mảng thay vì chỉ số.
- *(p+3) cho giá trị a[3].
a[i] = *(p+i)
Chương trình ví dụ
Chương trình C cho con trỏ và mảng 1 chiều:
#include <stdio.h>
main() {
int a[5];
int *p, i;
printf("Nhập 5 phần tử: ");
for (i = 0; i < 5; i++)
scanf("%d", &a[i]);
p = &a[0];
printf("Phần tử mảng: ");
for (i = 0; i < 5; i++)
printf("%d", *(p + i));
}
Kết quả
Nhập 5 phần tử: 10 20 30 40 50 Phần tử mảng: 10 20 30 40 50