
Tham khảo toàn diện về Con trỏ trong C/C++
NhatPhuongLe
w w w .rea on line .n et
MỤC LỤC
I. Con trỏ....................................................................................................................................... 3
1. Một số khái niệm.............................................................................................................................3
2. Biến...................................................................................................................................................3
a) Biến .................................................................................................................................... 3
b) Ví dụ................................................................................................................................... 4
3. Con trỏ................................................................................................................................... 5
a) Khái niệm.....................................................................................................................................6
b) Tại sao phải dùng con trỏ...........................................................................................................7
c) Một số thao tác cơ bản với con trỏ............................................................................................9
II. Con trỏ hàm ............................................................................................................................. 11
1. Một số khái niệm ................................................................................................................. 11
2. Con trỏ hàm.......................................................................................................................... 11
a) Khái niệm...................................................................................................................................11
b) Cú pháp.......................................................................................................................................12
c) Định nghĩa một con trỏ hàm.....................................................................................................12
3. Kiểu quy ước gọi của hàm ................................................................................................... 13
4. Gán một hàm (địa chỉ hàm) vào/cho con trỏ hàm ............................................................... 13
5. Gọi hàm sử dụng con trỏ hàm.............................................................................................. 15
6. Tại sao sử dụng con trỏ hàm................................................................................................ 16
7. Định nghĩa con trỏ hàm bằng từ khóa typedef..................................................................... 20
III. Tài liệu tham khảo ................................................................................................................... 21
Trang 2
Re verse Engineering Associa t ion

Tham khảo toàn diện về Con trỏ trong C/C++
NhatPhuongLe
w w w .rea on line .n et
I. Con trỏ
1. Một số khái niệm
Con trỏ (pointer) đơn giản là địa chỉ của một đối tượng trong bộ nhớ. Thông
thường, các đối tượng có thể được truy xuất bằng một trong 2 cách: trực tiếp bằng đại
diện hoặc gián tiếp bằng con trỏ. Các biến con trỏ được định nghĩa trỏ tới các đối tượng
có một kiểu dữ liệu cụ thể sao cho khi con trỏ bị hủy đi thì vùng nhớ mà đối tượng đuợc
cấp phát sẽ được giải phóng hoặc thu hồi.
Các con trỏ thường được dùng để tạo ra các đối tượng động trong lúc thực thi
chương trình. Không giống như các đối tượng bình thường (biến cục bộ và toàn cục)
được cấp phát và lưu trữ trong ngăn xếp (stack), một đối tượng động được cấp phát vùng
nhớ từ vùng lưu trữ khác được gọi là heap. Các đối tượng không tuân theo quy luật thông
thường. Phạm vi của chúng được điều khiển bởi các lập trình viên.
Tham chiếu (reference) cung cấp một tên tượng trưng cho đối tượng, gọi là alias
(tên đại diện). Truy xuất một đối tượng thông qua một tham chiếu giống như truy xuất
thông qua tên của đối tượng. Tham chiếu nâng cao tính hữu dụng của con trỏ và sự tiện
lợi của việc truy xuất trực tiếp các đối tượng. Chúng được sử dụng để hổ trợ gọi thông
qua tham chiếu của các tham số hàm đặc biệt khi các đối tượng lớn được truyền tới hàm.
2. Biến
Khái niệm con trỏ trong ngôn ngữ C/C++ là một phần quan trọng và khá phức tạp,
mang lại rất nhiều tiện lợi cũng như rắc rối. Nếu như muốn giải thích cặn kẽ về vai trò,
chức năng, hoạt động cũng như những khái niệm khác liên quan tới con trỏ thì tôi e rằng
cần khoảng vài chương sách mới đủ. Tôi tạm mượn câu nói “Ngôn ngữ C/C++ không
phải chỉ có con trỏ, nhưng nếu chưa hiểu về con trỏ thì kể như chưa học C/C++” để nói
lên vài trò của con trỏ. Bởi vì nhiều khái niệm khác trong C liên quan mật thiết tới con trỏ
như: chuỗi ký tự, mảng, hàm CallBack, các kiểu dữ liệu trừu tượng như danh sách liên
kết, cấu trúc cây, ... và mở rộng ra trong C++ như lớp, các hàm thành viên, V-Table, ...
a) Biến
Để hiểu được con trỏ thì trước tiên bạn phải hiểu về biến. Trong C/C++, biến là một
vùng trong bộ nhớ, do đó mỗi biến đều có 1 địa chỉ. Khi bạn khai báo một biến, bạn phải
cung cấp tên biến, kiểu dữ liệu của biến đó. Khi bạn muốn thao tác với một biến thì bạn
sử dụng tên gọi của nó, còn kiểu dữ liệu giúp cho trình biên dịch biết là biến đó cần bao
nhiêu byte trong bộ nhớ và nó sẽ cấp phát vùng nhớ tương ứng cho biến đó. Ví dụ, bạn
khai báo 1 biến kiểu integer:
int var;
Trang 3
Re verse Engineering Associa t ion

Tham khảo toàn diện về Con trỏ trong C/C++
NhatPhuongLe
w w w .rea on line .n et
Khi biên dịch tới đây, trình biên dịch sẽ cấp phát bộ nhớ cho biến var này là 2 byte
hoặc 4 bytes (tùy thuộc vào kiến trúc máy tính). Giả sử kiểu int cần 2 bytes, và trình biên
dịch sẽ gán cho biến var hai byte trong bộ nhớ bắt đầu tại địa chỉ xxx. Sau đó, trình biên
dịch sẽ điền tên và địa chỉ của biến var này vào trong một bảng (chỉ sử dụng khi biên
dịch). Bạn có thể hiểu nôm na bảng này gồm 2 cột: một cột là tên biến và một cột là địa
chỉ của biến. Mỗi biến trong chuơng trình sẽ chiếm một dòng trong bảng đó, khi biên dịch
gặp dòng lệnh gán:
var = 25;
Đầu tiên, nó sẽ tìm xem trong bảng có biến nào tên là var hay không, nếu nó tìm
không thấy thì nó sẽ khai báo lỗi là bạn dùng một biến chưa khai báo:
error Cxxx: 'i' : undeclared identifier
Nếu tìm thấy biến này thì nó sẽ điền giá trị là 25 vào 2 byte tại địa chỉ xxx.
b) Ví dụ
Về cơ bản bộ nhớ máy tính là một dãy các bytes. Mỗi byte được đánh địa chỉ cụ
thể. Hình dưới đây tượng trưng một dãy bytes, từ địa chỉ 924 tới địa chỉ 940, trong bộ
nhớ máy tính:
Bạn có chương trình như sau:
Mã lệnh C Mã lệnh C++
1: #include <stdio.h> 1: #include <iostream>
2: int main () 2: int main ()
3: { 3: {
4: float fl=3.14; 4: float fl=3.14;
5: printf (“%.2f\n”,fl) 5: std::count << fl << std::endl
6: return 0; 6: return 0;
7: } 7: }
Khi biên dịch tới dòng (4) của chương trình, thì trình biên dịch sẽ cấp vùng nhớ
cho biến fl. Trong ví dụ này, giả sử rằng biến float cần 4 bytes:
Trang 4
Re verse Engineering Associa t ion

Tham khảo toàn diện về Con trỏ trong C/C++
NhatPhuongLe
w w w .rea on line .n et
Khi biến fl được sử dụng ở dòng (5), trình biên dịch sẽ làm 2 bước như sau:
+ Chương trình sẽ tìm và lấy địa chỉ dành cho biến fl (trong ví dụ này là 924)
+ Lấy nội dung lưu tại địa chỉ 924
Tổng quát lên, khi bất kỳ một biến nào đó được sử dụng, thì trình biên dịch
cũng làm 2 bước trên để lấy nội dung của biến.
Minh họa giá trị của biến được khởi tạo lưu trữ trong bộ nhớ máy tính có thể bị hiểu
nhầm. Hãy nhìn hình, giá trị 3 đựơc lưu tại địa chỉ 924, dấm chấm được lưu tại địa chỉ 925,
giá trị 1 được lưu tại đại chỉ 926, và cuối cùng giá trị 4 đựơc lưu tại địa chỉ 927. Hãy luôn
nhớ rằng, trong thực tế máy tính sẽ sử dụng một thuật toán để chuyển đổi số kiểu chấm
động (float point number) 3.14 thành dãy các bit 0 và 1. Mỗi byte có 8 bits 0 và 1, vì thế 4
bytes float sẽ lưu trữ 32 bits 0 và 1. Bất kể con số này là 3.14 hay -273.15, thì nó luôn luôn
được lưu trữ trong 4 bytes bộ nhớ.
3. Con trỏ
Ví dụ trên minh họa cho chúng ta cách khai báo, sử dụng cũng như biểu diễn
chúng trên bộ nhớ như thế nào. Đây là các biến có kích thước và kiểu dữ liệu xác
định. Người ta gọi các biến kiểu này là biến tĩnh. Khi khai báo biến tĩnh, việc cấp
phát vùng nhớ cho các biến này luôn luôn được thực hiện mà không cần biết trong
quá trình thực thi chương trình có sử dụng hết vùng nhớ đã được cấp hay không?
Mặt khác, các biến tĩnh dạng này sẽ tồn tại trong suốt thời gian thực thi chương trình
mặc dù có những biến chỉ được sử dụng trong suốt chương trình.
Một số hạn chế có thể gặp phải khi sử dụng các biến tĩnh:
Cấp phát vùng nhớ thừa lãng phí vùng nhớ
Cấp phát vùng nhớ thiếu, chương trình thực thi bị lỗi.
Để tránh những hạn chế trên, ngôn ngữ C cung cấp cho ta một loại biến đặc biệt
gọi là biến động với các đặc điểm sau:
Chỉ phát sinh trong quá trình thực hiện chương trình chứ không phát
sinh lúc bắt đầu chương trình.
Khi chạy chương trình, kích thước của biến, vùng nhớ và địa chỉ vùng
nhớ được cấp phát cho biến có thể thay đổi.
Sau khi sử dụng xong có thể giải phóng để tiết kiệm chỗ trong bộ nhớ.
Tuy nhiên các biến động không có địa chỉ nhất định nên ta không thể truy cập đến
chúng được. Vì thế, ngôn ngữ C lại cung cấp cho ta một loại biến đặc biệt nữa để khắc
phục tình trạng này, đó là biến con trỏ (pointer).
Trang 5
Re verse Engineering Associa t ion


