Bài giảng Lập trình C/C++ - Chương 7: Con trỏ - Lê Thành Sách

Nội dung

n Tổ chức bộ nhớ thực thi

n Ứng dụng của con trỏ

n Mô hình của con trỏ

n Toán tử &

n Khai báo trỏ

n Toán tử *

n Các phép toán trên con trỏ

n Con trỏ và mảng

n Cấp phát bộ nhớ động

n Con trỏ và cấu trúc, toán tử ->

n Các chủ đề nâng cao với con trỏ

n Thứ tự đánh giá * và ++, --

n Con trỏ và const

n Con trỏ đến con trỏ

n Con trỏ void

pdf 51 trang phuongnguyen 3560
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình C/C++ - Chương 7: Con trỏ - Lê Thành Sách", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

Tóm tắt nội dung tài liệu: Bài giảng Lập trình C/C++ - Chương 7: Con trỏ - Lê Thành Sách

Bài giảng Lập trình C/C++ - Chương 7: Con trỏ - Lê Thành Sách
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
1
Chương 07
CON TRỎ
Lê Thành Sách
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
2
Nội dung
n Tổ chức bộ nhớ thực thi
n Ứng dụng của con trỏ
n Mô hình của con trỏ
n Toán tử &
n Khai báo trỏ
n Toán tử *
n Các phép toán trên con trỏ
n Con trỏ và mảng
n Cấp phát bộ nhớ động
n Con trỏ và cấu trúc, toán tử ->
n Các chủ đề nâng cao với con trỏ
n Thứ tự đánh giá * và ++, --
n Con trỏ và const
n Con trỏ đến con trỏ
n Con trỏ void
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
3
Tổ chức bộ nhớ thực thi
n Khi chương trình được 
lên bộ nhớ để thực thi, hệ 
thống tổ chức bộ nhớ như 
hình vẽ
(Nguồn: 
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
4
Tổ chức bộ nhớ thực thi
n Vùng “text”
n Chứa mã thực thi của 
chương trình
n Vùng này chỉ đọc
n Vùng này có thể dùng 
chung trong trường hợp 
chương trình thực thi 
thường xuyên
(Nguồn: 
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
5
Tổ chức bộ nhớ thực thi
n Vùng “Data”
n Gồm:
n Dữ liệu được khởi động 
(bởi người lập trình)
n Dữ liệu không được 
khởi động 
(bởi người lập trình)
(Nguồn: 
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
6
Tổ chức bộ nhớ thực thi
n Vùng “Data”
n Gồm:
n Dữ liệu được khởi động 
(bởi người lập trình)
n Biến toàn cục
n Biến tĩnh (static)
n Vùng này gồm hai vùng 
con:
n Chỉ đọc
n Ví dụ: Hằng chuỗi
n Đọc/ghi
n Các biến static và 
global không hằng
(Nguồn: 
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
7
Tổ chức bộ nhớ thực thi
n Vùng “Data”
n Gồm:
n Dữ liệu được khởi động
n Dữ liệu không khởi động 
bởi người lập trình
n Biến toàn cục 
n Biến tĩnh (static)
n Hệ thống khởi động 
về 0 (số) cho các 
biến không được 
người lập trình chủ 
động khởi động
(Nguồn: 
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
8
Tổ chức bộ nhớ thực thi
n Vùng “HEAP”
n Chứa bộ nhớ xin cấp phát 
động bởi người lập trình
n Liên quan đến Kiểu dữ liệu 
con trỏ nói trong chương 
này
(Nguồn:  programming.org/)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
9
Tổ chức bộ nhớ thực thi
n Vùng “STACK”
n Chứa
n Các biến được khai báo 
trong chương trình
n Thông tin mỗi lần gọi 
hàm
(Nguồn:  programming.org/)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
10
Ứng dụng của con trỏ
n Mảng trong C 
n Phải biết trước số lượng phần tử tại thời điểm viết chương trình
n Do đó, cần phải khai báo một số lượng lớn các ô nhớ để sẵn. Tuy 
nhiên, tại một thời điểm nào đó, chương trình có thể sẽ sử dụng ít 
hơn rất nhiều à lãng phí
n Yêu cầu: Có thể nào dùng mảng với số lượng phần tử chỉ cần biết 
lúc chương trình đang chạy?
n => Cần con trỏ
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
11
Ứng dụng của con trỏ
n Mảng trong C 
n Khi thêm vào và lấy ra các phần tử trên mảng 
n => cần phải dịch phải và trái nhiều phần tử à tốn nhiều thời gian
n Yêu cầu: Có cách tổ chức dữ liệu nào giúp các phép quản lý phần 
tử nói trên nhanh chóng
n => Sử dụng danh sách liên kết
n => Cần đến con trỏ
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
12
Mô hình của con trỏ
0x1234 FFFF Biến p: là con trỏ
Chứa địa chỉ của biến x, nghĩa là giá trị
0x1234 FFFF
Biến a: là biến có kiểu nào đó bất kỳ
Ô nhớ bắt đầu của a có địa chỉ là: (ví dụ)
0x1234 FFFF
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
13
Mô hình của con trỏ
Biến p: là con trỏ
Chứa địa chỉ của biến x, nghĩa là giá trị
0x1234 FFFF
Biến a: là biến có kiểu nào đó bất kỳ
Ô nhớ bắt đầu của a có địa chỉ là: (ví dụ)
0x1234 FFFF
Minh hoạ con trỏ bởi tên từ ô nhớ biến p 
CHỈ ĐẾN (point to) ô nhớ biến x
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
14
Toán tử &
n Con trỏ lưu trữ địa chỉ của một ô nhớ (biến) khác è Bằng 
cách nào lấy địa chỉ của một biến hay ô nhớ để gán cho 
biến con trỏ
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
15
Toán tử &
n Con trỏ lưu trữ địa chỉ của một ô nhớ (biến) khác è Bằng 
cách nào lấy địa chỉ của một biến hay ô nhớ để gán cho 
biến con trỏ
n Cách 1: Dùng toán tử & để lấy địa chỉ của một biến đang có
n Cách 2: Xin cấp phát bộ nhớ động (phần sau)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
16
Toán tử &
n Toán tử & trả về địa chỉ của một biến
n Ví dụ
#include 
#include 
int main(){
int a = 100;
printf("%d\n", a);
printf("%p\n", &a);
system("pause");
return 0;
}
In ra giá trị của a
In ra địa chỉ của a
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
17
Toán tử &
n Toán tử & trả về địa chỉ của một biến
n Ví dụ
#include 
#include 
typedef struct sPoint3D{float x, y, z;} Point3D;
int main(){
Point3D p1 = {1.0f, 2.0f, 3.0f};
printf("%-5.1f\n", p1.x);
printf("%p\n", &p1);
printf("%p\n", &p1.x);
printf("%p\n", &p1.y);
printf("%p\n", &p1.z);
system("pause");
return 0;
}
In ra giá trị của p1.x
In ra địa chỉ của p1
In ra địa chỉ của p1.x
In ra địa chỉ của p1.y
In ra địa chỉ của p1.z
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
18
Khai báo con trỏ
Cú pháp
 * ;
 * = 0;
 * = &;
: Phải có kiểu , hoặc 
có kiểu chuyển đổi qua được 
0: Hằng số, gọi là NULL
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
19
Khai báo con trỏ
Cú pháp
int a;
int *p1;
int *p2 = 0;
int *p3 = &a;
double d;
double *pd1;
double *pd2 = 0;
double *pd3 = &d;
float f;
float *pf1;
float *pf2 = 0;
float *pf3 = &d;
Point3D p1 = {1.0f, 2.0f, 3.0f};
Point3D *pp1;
Point3D *pp2 = 0;
Point3D *pp3 = &p1;
a: là số nguyên
p1: con trỏ đến số nguyên, giá trị chưa xác định
p2: con trỏ đến số nguyên, giá trị là NULL
p3: con trỏ đến số nguyên, giá trị chính là địa chỉ 
của số nhớ a
f: là số float
pf1: con trỏ đến số float, giá trị chưa xác định
pf2: con trỏ đến số float, giá trị là NULL
pf3: con trỏ đến số float, giá trị chính là địa chỉ 
của số nhớ f
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
20
Toán tử *
n Toán tử * lấy giá trị (tham khảo) tại một địa chỉ
n Toán tử & lấy địa chỉ của biến
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
21
Toán tử *
#include 
#include 
int main(){
int a = 100;
printf("a=%d\n", a);
printf("*&a=%d\n", *&a);
printf("*&*&a=%d\n", *&*&a);
printf("*&*&*&a=%d\n", *&*&*&a);
system("pause");
return 0;
}
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
22
Các phép toán trên con trỏ
n Tăng và Giảm: ++, --
n Cộng và trừ: +, -
n Cộng và trừ kết hợp gán: +=, -=
n So sanh: ==, != 
Gọi p là con trỏ có kiểu T: T *p;
Các phép cộng và trừ: làm con trỏ p tăng hay giảm một bội số của 
kích thước kiểu T.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
23
Con trỏ và mảng
n Con trỏ và mảng có nhiều điểm giống nhau
n Con trỏ & mảng: giữ địa chỉ của ô nhớ
n Con trỏ: giữa địa chỉ của ô nhớ nào đó (của biến khác, của bộ 
nhớ động)
n Mảng: giữ địa chỉ của phần tử đầu tiên
n => có thể gán mảng vào con trỏ
n Tuy nhiên, gán con trỏ vào mảng là không được
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
24
Con trỏ và mảng
#include 
#include 
int main(){
int a[5];
int *p = a;
printf("a =%p\n", a);
printf("p =%p\n", p);
system("pause");
return 0;
}
Có thể gán con trỏ 
mảng vào con trỏ
=>
A và p có giữ cùng 
địa chỉ: địa chỉ của ô 
đầu tiên trên mảng
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
25
Con trỏ và mảng
n Con trỏ và mảng có nhiều điểm giống nhau
n Có cùng cách truỳ cập các ô nhớ
n Dùng toán tử [ ]
n Dùng toán tử * và +
int a[5];
int *p = a;
int id = 2;
a[id] = 100;
p[id] = 100;
*(a + id) = 100;
*(p + id) = 100;
Giống nhau
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
26
Con trỏ và mảng
n Con trỏ và mảng cũng có điểm khác nhau
n Mảng: các phần tử của mảng nằm trên STACK của chương trình
n Con trỏ: Các phần tử mảng con trỏ chỉ đến có thể trên STACK hay 
HEAP
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
27
Cấp phát bộ nhớ động
n Giúp người lập trình tạo ra mảng động. Không cần xác định 
số lượng phần tử của mảng động tại thời điểm biên dịch 
như mảng tĩnh
n Mảng động sẽ được cấp phát trên HEAP
Mỗi khi xin cấp phát bộ nhớ 
CẦN PHẢI giải phóng vùng nhớ xin được khi dùng xong
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
28
Cấp phát bộ nhớ động
n Hàm xin bộ nhớ
n malloc
n calloc
n realloc
n Hàm giải phóng bộ nhớ
n free
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
29
Cấp phát bộ nhớ động
malloc
#include 
#include 
typedef struct sPoint3D{float x, y, z;} Point3D;
int main(){
int *p1;
float *p2;
Point3D *p3;
int num = 100;
p1 = (int*)malloc(num*sizeof(int));
p2 = (float*)malloc(num*sizeof(float));
p3 = (Point3D*)malloc(num*sizeof(Point3D));
free(p1); free(p2); free(p3);
return 0;
}
Các biến con trỏ
Xin cấp bộ nhớ
Giải phóng bộ nhớ
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
30
Cấp phát bộ nhớ động
malloc
p1 = (int*)malloc(num*sizeof(int));
num: số con số int cần xin
sizeof(int): kích thước của mỗi số nguyên.
è num*sizeof(int): số bytes cần thiết để xin
(Đối số truyền vào hàm malloc là số bytes bộ nhớ cần xin)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
31
Cấp phát bộ nhớ động
malloc
p1 = (int*)malloc(num*sizeof(int));
Hàm malloc trả về kiểu void* (kiểu vô định). 
Cần ép vào kiểu của bên tay trái
p1: kiểu int* è ép vào int* bằng (int*)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
32
Cấp phát bộ nhớ động
malloc
#include 
#include 
int main(){
int num = 100;
int *p1 = (int*)malloc(num*sizeof(int));
if(p1 == NULL){
printf("Xin khong duoc!\n");
exit(1);
}
else{
//Thuc hien cong viec tai day
free(p1);
}
return 0;
}
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
33
Cấp phát bộ nhớ động
malloc
int *p1 = (int*)malloc(num*sizeof(int));
if(p1 == NULL){ ...} else { ...}
Hàm malloc trả về NULL nếu không xin được.
Lúc đó, không thể dùng bộ nhớ được!
Do đó, LUÔN LUÔN kiểm tra xem malloc có trả về NULL hay không
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
34
Cấp phát bộ nhớ động
Ví dụ
typedef struct{
float x, y, z;
} Point3D;
int main(){
int num = 20;
int *int_ptr = (int*)malloc(num*sizeof(int));
char *str = (char*)malloc(num*sizeof(char));
double *double_ptr = (double*)malloc(num*sizeof(double));
Point3D *p_ptr = (Point3D*)malloc(num*sizeof(Point3D));
//Su dung
free(int_ptr);
free(str);
free(double_ptr);
free(p_ptr);
return 0;
}
Khai báo biến con trỏ đến các 
kiểu + xin cấp phát bộ nhớ động
Giải phóng các vùng nhớ sau khi sử dụng
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
35
Con trỏ và cấu trúc
Khai báo
typedef struct{
float x, y, z;
} Point3D;
Point3D *p_ptr = (Point3D*)malloc(sizeof(Point3D));
// (4) Sử dụng
free(p_ptr);
(1) Định nghĩa kiểu cấu trúc: Point3D
(2) Khai báo con trỏ đến một mảng
(3) Xin cấp phát bộ nhớ trên HEAP,
p_ptr: giữ địa chỉ của ô nhớ đầu tiên trong 
vùng được cấp(5) Giải phóng vùng nhớ
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
36
Con trỏ và cấu trúc
Truy cập biến thành viên cấu trúc qua con trỏ
(*p_ptr).x = 4.5f; (*p_ptr).y = 5.5f; (*p_ptr).z = 6.5f; 
p_ptr->x = 7.5f; p_ptr->y = 8.5f; p_ptr->z = 9.5f; 
Ví dụ: gán các biến thành viên của cấu trúc Point3D
p_ptr : Ô nhớ (biến) chứa địa chỉ của một cấu trúc Point3D
(*p_ptr) : Nghĩa là vùng nhớ của cấu trúc Point3D
(*p_ptr).x : Nghĩa là vùng nhớ chứa biến x của cấu trúc Point3D
p_ptr->x : Nghĩa là vùng nhớ chứa biến x của cấu trúc Point3D, 
truy cập thông qua toán tử -> từ con trỏ p_ptr
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
37
Con trỏ và cấu trúc
Truy cập biến thành viên cấu trúc qua con trỏ
(*p_ptr).x = 4.5f; (*p_ptr).y = 5.5f; (*p_ptr).z = 6.5f; 
p_ptr->x = 7.5f; p_ptr->y = 8.5f; p_ptr->z = 9.5f; 
Ví dụ: gán các biến thành viên của cấu trúc Point3D
Tổng quát:
 -> 
Như:
p_ptr->x
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
38
Con trỏ và cấu trúc
Chương trình minh hoạ
# include 
# include 
typedef struct{
float x, y, z;
} Point3D;
int main(){
Point3D p = {1.5f, 2.5f, 3.5f};
Point3D *p_ptr = (Point3D*)malloc(sizeof(Point3D));
(*p_ptr).x = 4.5f; (*p_ptr).y = 5.5f; (*p_ptr).z = 6.5f; 
p_ptr->x = 7.5f; p_ptr->y = 8.5f; p_ptr->z = 9.5f; 
printf("p = [%-4.1f, %-4.1f, %4.1f]\n", 
p.x, p.y, p.z);
printf("*p_ptr = [%-4.1f, %-4.1f, %4.1f]\n", 
(*p_ptr).x, (*p_ptr).y, (*p_ptr).z);
printf("*p_ptr = [%-4.1f, %-4.1f, %4.1f]\n", 
p_ptr->x, p_ptr->y, p_ptr->z);
free(p_ptr);
system("pause");
return 0;
} CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
39
Thứ tự các phép toán *, ++ và --
v*p++ // *(p++)
v*++p // *(++p)
v++*p // ++(*p)
v(*p)++ // Tăng vùng nhớ do con trỏ p chỉ đến
Khi nghi ngờ, hoặc không nhớ  hãy dùng toán tử 
() để phân giải độ ưu tiên
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
40
Con trỏ và const
int a = 20, b = 30, c = 40;
const int * ptr1 = &a;
//int const * ptr1 = &a;
int* const ptr2 = &b;
ptr1: có thể thay đổi được.
Giá trị mà ptr1 chỉ đến không thể 
thay đổi được
ptr1:
Ô nhớ ptr1 chỉ đến
(Không thể thay đổi được thông qua ptr1)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
41
Con trỏ và const
int a = 20, b = 30, c = 40;
const int * ptr1 = &a;
int* const ptr2 = &b;
ptr2: Không thể thay đổi được 
giá trị của ptr2 = không thể làm 
ptr2 chỉ đến ô nhớ nào khác sau 
dòng này.
Giá trị mà ptr2 chỉ đến có thể thay 
đổi được qua tr.
ptr2:
Ô nhớ ptr2 chỉ đến
(Không thể thay 
đổi được ptr2)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
42
Con trỏ và const
Các lỗi thông dụng
Ptr3: là con trỏ hằng nhưng không được khởi động tương 
tự như cho ptr2
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
43
Con trỏ và const
Các lỗi thông dụng
Giá trị mà ptr1 chỉ đến không thay đổi được qua con trỏ ptr1.
Do đó, nó không thể nằm bên trái biểu thức gán
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
44
Con trỏ và const
Các lỗi thông dụng
Con trỏ ptr2 là hằng số, nó chỉ nhận giá trị khởi động
Sau đó, không thể làm ptr2 chỉ đến đối tượng nào khác
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
45
Con trỏ và const
Các lỗi thông dụng
ptr3: con trỏ bình thường, thay đổi được nó và giá trị nó chỉ đến
Gán con trỏ ptr1 vào ptr3: khiến cho giá trị mà ptr1 chỉ đến có thể thay đổi được 
à bộ biên dich không cho phép.
Vì nếu cho phép thì ý nghĩa của ptr1 không còn. 
Người lập trình luôn luôn có thể thay đổi nội dung mà ptr1 chỉ đến, bằng cáhch dùng 
con trỏ phụ.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
46
Con trỏ và const
Các lỗi thông dụng
ptr3: con trỏ bình thường, thay đổi được nó và giá trị nó chỉ đến
Gán con trỏ ptr1 vào ptr3: khiến cho giá trị mà ptr1 chỉ đến có thể thay đổi được 
à bộ biên dich không cho phép.
Vì nếu cho phép thì ý nghĩa của ptr1 không còn. 
Người lập trình luôn luôn có thể thay đổi nội dung mà ptr1 chỉ đến, bằng cáhch dùng 
con trỏ phụ.
-> OK
-> LỖI
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
47
Con trỏ và const
Các lỗi thông dụng
ptr2: không thể thay đổi giá trị được
-> OK
-> LỖI
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
48
Con trỏ đến con trỏ
int* px = &x;
int x;
int** ppx = &px;
int*** ppx = &ppx;
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
49
Con trỏ đến con trỏ
10
int* px = &x;
int x;
int** ppx = &px;
int*** ppx = &ppx;
x = 10;
*px = 10;
**ppx = 10;
***pppx = 10;
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
50
Con trỏ void
n void *ptr: là con trỏ chưa định kiểu
n Có thể được ép kiểu về kiểu mong muốn
n Như các hàm malloc và free
n Con trỏ void giúp chương trình uyển chuyển,
n Nhưng rủi ro đi kèm: bộ biên dịch không thể kiểm tra tương thích 
kiểu tại thời điểm biên dịch
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa
Trung Tâm Kỹ Thuật Điện Toán
© 2016
Lập trình C/C++
51
Bài tập
n Hiện thực lại các bài tập về array nhưng dữ liệu các array 
nằm trên bộ nhớ HEAP
CuuDuongThanCong.com https://fb.com/tailieudientucntt

File đính kèm:

  • pdfbai_giang_lap_trinh_cc_chuong_7_con_tro_le_thanh_sach.pdf