Chương 5
Nội dung trình bày
1.
Địa chỉ
2.
Khái niệm và khai báo biến con trỏ
3.
Toán tử con trỏ
4.
Các thao tác trên biến con trỏ
5.
Cấp phát và giải phóng bộ nhớ
6.
Con trỏ và mảng
7.
Mảng con trỏ
2
1. Địa chỉ (Address)
Mỗi
biến đều có 2 thuộc tính: địa chỉ
(address) và giá trị (value)
◦ Ví dụ: int i=11, j=22, k=33;
Trong bộ nhớ:
+ Tại địa chỉ 53AD78 có giá trị là 11
+ Tại địa chỉ 53AD7C có giá trị là 22
+ Tại địa chỉ 53AD80 có giá trị là 33
Để
lấy địa chỉ của 1 biến: dùng dấu & trước
tên biến. Ví dụ:…
3
Nội dung trình bày
1.
Địa chỉ
2.
Khái niệm và khai báo biến con trỏ
3.
Toán tử con trỏ
4.
Các thao tác trên biến con trỏ
5.
Cấp phát và giải phóng bộ nhớ
6.
Con trỏ và mảng
7.
Mảng con trỏ
4
2. Khái niệm và khai báo con
trỏ
Khái
niệm con trỏ: Là một biến mà giá trị của
nó chứa một địa chỉ
Cách khai báo biến con trỏ: tương tự khai báo
biến thơng thường, có thêm dấu * vào trước
tên biến
Ví dụ:
int *ia;
int x, *p, *q;
Khơng được dùng biến con trỏ khi con trỏ
chưa được khởi tạo giá trị
Giá trị gán cho con trỏ phải là một địa chỉ, ví
dụ:
p = &x;
5
2. Khái niệm và khai báo con
trỏ:
Ví dụ
int i=11, j=22, k=33;
int *iPtr, *jPtr, *kPtr;
iPtr = &i;
jPtr = &j;
iPtr, jPtr là 2 biến con trỏ lần
lượt chứa địa chỉ của i, j
Vậy: nếu gán iPtr = i là sai
6
Nội dung trình bày
1.
Địa chỉ
2.
Khái niệm và khai báo biến con trỏ
3.
Toán tử con trỏ
4.
Các thao tác trên biến con trỏ
5.
Cấp phát và giải phóng bộ nhớ
6.
Con trỏ và mảng
7.
Mảng con trỏ
7
3. Toán tử con trỏ
Toán
tử * : lấy giá trị tại địa chỉ chứa trong
biến con trỏ
Ví
dụ:
int i;
int *ia;
i = 10;
ia = &i;
cout<<" Dia
cout<<" Gia
cout<<" Gia
<<"\n";
*ia = 50;
cout<<" Gia
1234
50
10
i
1234
ia
1236
1238
1240
chi cua i la: "<< ia <<"\n";
tri cua i tai dia chi do la: "<< i <<"\n";
tri cua i tai dia chi do la: "<< *ia
tri cua i bay gio la: "<
8
3. Tốn tử con trỏ: Ví dụ
// kết quả xuất ra màn hình
#include <iostream.h>
#include <conio.h> a = 15
b = 20
void main ()
{
int a = 20, b = 15, *pa, *pb, temp;
pa = &a; // con trỏ pa chứa địa chỉ của a
pb = &b; // con trỏ pb chứa địa chỉ của b
temp = *pa;
*pa = *pb;
*pb = temp;
cout << "a = " << a << endl;
cout << “b = ” << b;
}
9
Nội dung trình bày
1.
Địa chỉ
2.
Khái niệm và khai báo biến con trỏ
3.
Toán tử con trỏ
4.
Các phép toán số học trên con trỏ
5.
Cấp phát và giải phóng bộ nhớ
6.
Con trỏ và mảng
7.
Mảng con trỏ
10
4. Các phép toán số học trên
con trỏ
Phép
gán
Phép cộng, trừ một con trỏ với một số
nguyên
Phép tăng, giảm
11
4. Các phép toán số học trên
con trỏ (tt)
Phép
gán con trỏ
◦ Hai biến con trỏ cùng kiểu có thể gán cho
nhau
Ví
dụ:
int x;
int *p1, *p2;
p1 = &x;
p2 = p1;
Sau khi đoạn lệnh trên được thực hiện, cả
p1 và p2 cùng trỏ đến biến x
12
4. Các phép toán số học trên
con trỏ (tt)
Phép
cộng, trừ một con trỏ với một số
nguyên
◦ Khi cộng hoặc trừ 1 con trỏ với 1 số nguyên N;
kết quả trả về là 1 con trỏ
◦ Con trỏ này sẽ chỉ đến vùng nhớ cách vùng
nhớ của con trỏ hiện tại một số nguyên lần
kích thước của kiểu dữ liệu của nó
13
4. Các phép tốn số học trên
con trỏ (tt)
Ví dụ :
char *a;
short *b;
long *c;
Giả sử các con trỏ a, b, c lần lượt trỏ tới ô nhớ
1000, 2000 và 3000
a = a + 1; // con trỏ a dời đi 1 byte
b = b + 1; // con trỏ b dời đi 2 byte
c = c + 1; // con trỏ c dời đi 4 byte
14
4. Các phép toán số học trên
con trỏ (tt)
15
Nội dung trình bày
1.
Địa chỉ
2.
Khái niệm và khai báo biến con trỏ
3.
Toán tử con trỏ
4.
Các phép toán số học trên con trỏ
5.
Cấp phát và giải phóng bộ nhớ
6.
Con trỏ và mảng
7.
Mảng con trỏ
16
5. Cấp phát và giải phóng bộ
nhớ
Cấp
phát động là phương tiện nhờ đó một
chương trình có thể dành thêm bộ nhớ
trong khi đang thực thi hoặc giải phóng bộ
nhớ khi khơng cần thiết
C/C++
có hai hệ thống cấp phát động: một
hệ thống được định nghĩa bởi C và một được
định nghĩa bởi C++
17
5. Cấp phát và giải phóng bộ
nhớ
Cấp
phát và giải phóng bộ nhớ động được định
nghĩa bởi C, trong thư viện stdlib.h
◦ void *malloc(length): dùng để cấp phát bộ nhớ
length: là số byte muốn cấp phát
Hàm malloc() trả về một con trỏ có kiểu void, do đó
có thể ép kiểu nó cho con trỏ có kiểu bất kỳ
Sau khi cấp phát thành công, hàm malloc() trả về
địa chỉ của byte đầu tiên của vùng nhớ. Nếu không
thành cơng (khơng có đủ vùng nhớ), hàm malloc()
trả về null
◦ void free(void *p): dùng để thu hồi bộ nhớ
được cấp phát bởi hàm malloc
18
5. Cấp phát và giải phóng bộ
nhớ
Ví
dụ 1:
char *p;
p = (char *) malloc(1000); //cấp phát 1000 bytes
Vì hàm malloc() trả về con trỏ kiểu void,
nên phải ép kiểu nó thành con trỏ char cho
phù hợp với biến con trỏ p
Ví dụ 2:
int *p;
p = (int *) malloc(50*sizeof(int));
…
free(p);
19
5. Cấp phát và giải phóng bộ
nhớ
Cấp
phát và giải phóng bộ nhớ động được
định nghĩa bởi C++
◦ Tốn tử new cấp phát bộ nhớ và trả về một
con trỏ đến byte đầu tiên của vùng nhớ được
cấp phát
◦ Toán tử delete thu hồi vùng nhớ được cấp
phát trước đó bởi toán tử new
20
5. Cấp phát và giải phóng bộ
nhớ
Ví
dụ:
#include <iostream.h>
void main()
{
int *p;
p = new int;
// cấp phát vùng nhớ cho p
*p = 100;
cout << "At " << p;
cout << " is the value " << *p << "\n";
delete p;
}
21
Nội dung trình bày
1.
Địa chỉ
2.
Khái niệm và khai báo biến con trỏ
3.
Toán tử con trỏ
4.
Các phép toán số học trên con trỏ
5.
Cấp phát và giải phóng bộ nhớ
6.
Con trỏ và mảng
7.
Mảng con trỏ
22
6. Con trỏ và mảng: Giới thiệu
Giữa
mảng và con trỏ có một sự liên hệ rất
chặt chẽ, xét ví dụ:
char ch[10], *p;
p = ch;
Tên của mảng hoặc con trỏ tương
đương với địa chỉ phần tử đầu tiên
của nó
23
6. Con trỏ và mảng: Giới thiệu
(tt)
Những
phần tử của mảng được xác định bằng chỉ
số và cũng có thể được xác định qua biến con trỏ
◦ Ví dụ, để truy cập phần tử thứ 3 trong mảng, ta
dùng 1 trong 2 cách: ch[2] hoặc *(p+2)
Truy
cập các phần tử mảng bằng con trỏ:
Kiểu mảng
Kiểu con trỏ
&Tên_mảng[0]
Tên_con_trỏ
&Tên_mảng[Vị_trí]
Tên_con_trỏ + Vị_trí
Tên mảng[Vị_trí]
*(Tên_con_trỏ + Vị_trí)
Ví
dụ: …
24
6. Con trỏ và mảng: Ví dụ
int
Numbers[5];
int *p;
Numb
ers
p
p
p= Numbers;
*p =
10;
p++; *p =
p = 20;
*p = 30;
&numbers[2];
p
= numbers +*p = 40;
10
20
p
20
30
p
40
5
0
p
3;
p = numbers; *(p+4) =
50;
for (int n=0; n<5; n++)
cout << numbers[n] <<
", ";
25