LẬP TRÌNH CĂN BẢN
KIỂU CON TRỎ
Giảng viên: TS. Trương Quốc Bảo
NỘI DUNG CỦA CHƯƠNG
Giới thiệu kiểu dữ liệu con trỏ
Khai báo và sử dụng biến con trỏ
Con trỏ và mảng.
Con trỏ và tham số hình thức của hàm.
Thursday, January 15, 2015 Lập trình căn bản 2
GIỚI THIỆU KIỂU CON TRỎ (POINTER)
1 con trỏ là 1 biến được dùng để chứa địa chỉ
của ô nhớ trong bộ nhớ.
Kích thước của biến con trỏ luôn là 2 bytes.
pointer ptr variable a
3.145
Ví dụ: FFF2
FFF2 (address)
float a=3.145;
float* ptr; //ptr is a pointer
ptr=&a;
*ptr=20;
Thursday, January 15, 2015 Lập trình căn bản 3
KHAI BÁO BIẾN KIỂU CON TRỎ
Cú pháp:
<Kiểu> *<Tên con trỏ>;
Ý nghĩa: Khai báo một biến có tên là Tên con trỏ
dùng để chứa địa chỉ của các biến có kiểu Kiểu.
Lưu ý: Kiểu void dùng để khai báo 1 con trỏ tổng
quát, chưa chỉ vào bất cứ biến gì.
Ví dụ:
int a, b, *pa, *pb; //pa và pb sẽ chỉ đến biến int
float f, *fb; //fb sẽ chỉ đến biến float
void *ptr; //ptr sẽ chỉ vào bất kỳ biến kiểu gì
Thursday, January 15, 2015 Lập trình căn bản 4
THAO TÁC TRÊN BIẾN CON TRỎ
Truy cập địa chỉ và nội dung của biến con trỏ.
Cấp phát vùng nhớ cho biến con trỏ.
Cấp phát lại vùng nhớ cho biến con trỏ.
Giải phóng vùng nhớ cho biến con trỏ.
Một số phép tốn trên con trỏ.
Thursday, January 15, 2015 Lập trình căn bản 5
GÁN ĐỊA CHỈ BIẾN CHO CON TRỎ
Toán tử & dùng để định vị con trỏ đến địa chỉ của
một biến đang làm việc.
Cú pháp: <Tên biến con trỏ> = &<Tên biến>;
Giải thích: Ta gán địa chỉ của biến <Tên biến> cho
con trỏ <Tên biến con trỏ>.
Ví dụ:
int a=6;
int *c = &a; // &a là địa chỉ bộ nhớ của biến a
// Con trỏ c chỉ đến địa chỉ của biến a
Thursday, January 15, 2015 Lập trình căn bản 6
TRUY CẬP NỘI DUNG CỦA BIẾN
DO CON TRỎ QUẢN LÝ
Để truy cập đến nội dung của ô nhớ mà con trỏ chỉ
tới, ta sử dụng cú pháp:
*<Tên biến con trỏ>;
Với cách truy cập này thì *<Tên biến con trỏ> có thể
coi là một biến có kiểu được mơ tả trong phần khai
báo biến con trỏ.
Ví dụ: int a = 6; int *c = &a;
*c = 7; /*Thay đổi nội dung của biến a bằng
cách dùng địa chỉ của nó được chứa
trong con trỏ c - Tương đương a = 7*/
Thursday, January 15, 2015 Lập trình căn bản 7
TRUY CẬP NỘI DUNG CỦA BIẾN
DO CON TRỎ QUẢN LÝ
Lưu ý:
Sự tương thích kiểu: đoạn chương trình sau có lỗi
khơng tương thích kiểu.
int Bien_Nguyen;
float *Con_Tro_Thuc;
Con_Tro_Thuc=&Bien_Nguyen; // Lỗi!!!
Khi gán địa chỉ của một biến cho một biến con trỏ,
mọi sự thay đổi trên nội dung ô nhớ con trỏ chỉ tới
sẽ làm giá trị của biến thay đổi theo.
Thursday, January 15, 2015 Lập trình căn bản 8
CẤP PHÁT VÙNG NHỚ CHO BIẾN
CON TRỎ (1)
Có 2 cách để dùng được biến con trỏ
1. Cho nó chứa địa chỉ của 1 vùng nhớ đang tồn tại
int a=6;
int* c= &a; // &a là địa chỉ bộ nhớ của biến a
2. Cấp phát 1 vùng nhớ mới, rồi cho con trỏ chỉ
đến vùng nhớ này. pointer ptr
Ví dụ: FFFA 6
int* ptr; FFFA (address)
ptr = (int*)malloc(sizeof(int));
*ptr=6; Thursday, January 15, 2015 Lập trình căn bản 9
CẤP PHÁT VÙNG NHỚ CHO BIẾN
CON TRỎ (2)
Hàm void *malloc(size_t size): Cấp phát vùng nhớ
có kích thước là size (bytes).
Hàm void *calloc(nitems, size): Cấp phát vùng nhớ
có kích thước là nitems*size (bytes).
Ví dụ:
int a, *pa, *pb;
pa = (int*)malloc(sizeof(int)); /* Cấp phát vùng nhớ
có kích thước bằng với kích thước của một số nguyên */
pb= (int*)calloc(10, sizeof(int)); /* Cấp phát vùng
nhớ có thể chứa được 10 số nguyên*/
Thursday, January 15, 2015 Lập trình căn bản 10
CẤP PHÁT LẠI VÙNG NHỚ CHO
BIẾN CON TRỎ
Hàm void *realloc(void *block, size):
Ý nghĩa:
Cấp phát lại 1 vùng nhớ do con trỏ block quản lý, vùng
nhớ này có kích thước mới là size; khi cấp phát lại thì nội
dung vùng nhớ trước đó được copy đến vùng nhớ mới.
Kết quả trả về của hàm là địa chỉ đầu tiên của vùng nhớ
mới. Địa chỉ này có thể khác với địa chỉ được chỉ ra khi
cấp phát ban đầu. Trả về NULL nếu khơng cấp phát được.
Ví dụ: int a, *pa;
pa = (int*)malloc(sizeof(int)); /*Cấp phát vùng nhớ có
kích thước 2 bytes*/
pa = realloc(pa, 6); /*Cấp phát lại vùng nhớ
Thursday, January 15, 2015 Lập trình căn bản thước mới là 6 bytes*/ 11
có kích
GIẢI PHÓNG VÙNG NHỚ DO
BIẾN CON TRỎ QUẢN LÝ
Hàm void free(void *block): Giải phóng vùng
nhớ được quản lý bởi con trỏ block.
Ví dụ:
free(pa);
free(pb);
=> giải phóng vùng nhớ do
2 biến con trỏ pa và pb đang chỉ đến
Thursday, January 15, 2015 Lập trình căn bản 12
MỘT SỐ PHÉP TOÁN TRÊN
KIỂU CON TRỎ (1)
Phép gán và so sánh p a
10
Ví dụ: Hiện tại ta có: FFF2
FFF2 (address)
int a=10, b=15; b
int *p, *q; q 15
float *f; FFFA
FFFA (address)
p=&a; q=&b; p a
Bây giờ thì phép so sánh: FFFA
10
(p!=q) => true (1)
FFF2 (address)
Thực hiện tiếp lệnh gán: p=q; q b
Bây giờ thì: (p==q) => true (1) FFFA
15
Lệnh f=p; =>Error, do khác kiểu
FFFA (address)
ThursdNay,hJanưuanry 1g5, 2l0ệ15nh f=(float*)p; =Lập>trìNnh coăn beảnrror
13
MỘT SỐ PHÉP TOÁN TRÊN
KIỂU CON TRỎ (2)
Cộng, trừ con trỏ với 1 số nguyên
Ta có thể cộng (+), trừ (-) 1 con trỏ với 1 số nguyên N
nào đó.
Kết quả trả về là 1 con trỏ. Con trỏ này chỉ đến vùng
nhớ cách vùng nhớ của con trỏ hiện tại N phần tử.
Ví dụ: Cho đoạn chương trình sau:
int *pa, *pb, *pc;
pa = (int*) malloc(20); /*Cấp phát vùng nhớ 20 bytes*/
pb = pa + 7;
pc = pb - 3;
Thursday, JaLnuẳryc15,n20à15y hình ảnh của pLaập, trpìnhbcă,npbảcn như sau: 14
MỘT SỐ PHÉP TOÁN TRÊN
KIỂU CON TRỎ (3)
Cho con trỏ chỉ tới NULL
Ví dụ:
int x=25;
int *ptr;
ptr=&x;
ptr=NULL;
Lệnh gán ptr=NULL => cho con trỏ ptr không
trỏ vào (không chứa địa chỉ) vùng nhớ nào cả
Thursday, January 15, 2015 Lập trình căn bản 15
CON TRỎ VÀ MẢNG (1)
Mảng và con trỏ có mối liên
hệ với nhau
Thay vì truy cập 1 phần tử
mảng bằng chỉ số của nó, ta
có thể dùng 1 con trỏ
Để truy cập phần tử thứ i
của mảng, a[i], ta dùng:
y= *(pa+i);
Chú ý: pa+1 không phải
cộng 1 vào pa. Thay vào đó,
địa chỉ là pa+sizeof(*pa)
Thursday, January 15, 2015 Lập trình căn bản 16
CON TRỎ VÀ MẢNG (2)
1 mảng có thể được xem
như một con trỏ. Con trỏ
này đang chỉ đến phần tử
đầu tiên của mảng. Do đó:
1 mảng có thể được dùng
làm tham số cho 1 hàm:
Thursday, January 15, 2015 Lập trình căn bản 17
CON TRỎ VÀ MẢNG (3)
x sẽ có giá trị của a[i] nào, tại mỗi lệnh gán sau?
Lập trình căn bản 18
CON TRỎ VÀ THAM SỐ HÌNH
THỨC CỦA HÀM (1)
Ví dụ: Viết hàm hoán đổi nội dung 2 biến :
Thursday, January 15, 2015 Lập trình căn bản 19
CON TRỎ VÀ THAM SỐ HÌNH
THỨC CỦA HÀM (2)
Ví dụ: Viết lại hàm hoán đổi nội dung 2 biến như sau:
Thursday, January 15, 2015 Lập trình căn bản 20