▪ Cộng hoặc trừ với 1 số nguyên n trả về 1 con trỏ cùng kiểu, là địa chỉ mới trỏ tới 1 đối tượng khác nằm cách đối tượng đang bị trỏ n phần tử.. ▪ Trừ 2 con trỏ cho ta khoảng cách (số p[r]
(1)Bài 2
(2)Nội dung
1. Con trỏ
2. Quản lý nhớ
3. Hàm tham số
(3)1.
Con trỏ
(4)Con trỏ
Pointer
▪ Khái niệm
▫ Giá trị biến lưu trữ nhớ máy tính, truy cập tới giá trị qua tên biến, đồng thời qua địa chỉ chúng nhớ.
▪ Thực chất biến mà nội dung địa đối tượng khác (biến, hàm, số)
▫ Việc sử dụng trỏ cho phép ta truy nhập tới đối tượng gián tiếp qua địa
▪ Có nhiều kiểu biến với kích thước khác nhau, nên có nhiều kiểu trỏ
(5)Con trỏ
Pointer
▪ Khai báo trỏ :
▫ Syntax : dataType * PointerName;
Chỉ trỏ
▪ Sau khai báo, ta trỏ NULL (chưa trỏ tới đối tượng nào)
▫ Để sử dụng trỏ, ta dùng toán tử lấy địa & PointerName = &VarName
Ví dụ
int a; int *p; a=10; p= &a;
(6)Ví dụ
int i,j,*p; i= 5; p= & i;
j= *p; *p= j+2;
100 i 102 j 104 p
Gán i=5
100 5 i 102 j 104 p
100 5 i 102 j 104 100 p gán p = & i
gán j = *p
100 5 i 102 5 j 104 100 p
(7)Chú ý
▪ Một trỏ trỏ tới đối tượng kiểu
▪ Tốn tử ngơi * & có độ ưu tiên cao toán tử số học
▪ Ta viết *p cho nơi có đối tượng mà trỏ tới xuất
int x = 5, *p; p = & x; x=x+10; ~ *p = *p+10;
▪ Ta gán nội dung trỏ cho nhau: hai trỏ trỏ tới đối tượng
int x=10, *p, *q; p = &x; q = p;
(8)(9)Các phép toán trên con trỏ
▪ Cộng trừ với số nguyên n trả trỏ kiểu, địa trỏ tới đối tượng khác nằm cách đối tượng bị trỏ n phần tử
▪ Trừ trỏ cho ta khoảng cách (số phần tử) trỏ
▪ KHƠNG có phép cộng, nhân, chia trỏ
▪ Có thể dùng phép gán, so sánh trỏ
(10)Ví dụ
char *pchar; short *pshort; long *plong;
pchar ++; pshort ++; plong ++;
Giả sử địa ban đầu tương ứng trỏ 100, 200 300, kết ta có giá trị 101, 202 304 tương ứng
Nếu viết tiếp
(11)++ có độ ưu tiên cao * nên *p++ tương đương với *(p++)
tức tăng địa mà trỏ tới khơng phải tăng giá trị mà chứa
*p++ = *q++ tương đương với *p = *q;
p=p+1; q=q+1;
++*p = ++*q; //??? Dùng ( ) để tránh nhầm lẫn
(12)Con trỏ
void*
▪ Là trỏ khơng định kiểu Nó trỏ tới loại biến
▪ Thực chất trỏ void chứa địa nhớ mà địa có đối tượng kiểu liệu => truy cập nội dung đối tượng thông qua trỏ void
(13)Con trỏ
void*
float x; int y;
void *p; // khai báo trỏ void
p = &x; // p chứa địa số thực x
*p = 2.5; // báo lỗi p trỏ void
/* cần phải ép kiểu trỏ void trước truy cập đối tượng qua trỏ */
*((float*)p) = 2.5; // x = 2.5
p = &y; // p chứa địa số nguyên y
(14)Ví dụ
(float) *p=2.5;
*p= (float *) 2.5; *(float)p =2.5;
(float *) p =2.5; (float *) *p=2.5;
(15)Con trỏ và mảng
▪ Giả sử ta có int a[30]; &a[0] địa phần tử đầu
tiên mảng đó, đồng thời địa mảng
▪ Trong C, tên mảng địa = địa phần tử mảng
(16)Con trỏ và
mảng
▪ Tuy cần ý a => khơng thể dùng câu lệnh gán hay toán tử tăng, giảm a++;
▪ Xét trỏ: int *pa;
pa = &a[0];
=> pa trỏ vào phần tử thứ mảng
▪ pa +1 trỏ vào phần tử thứ mảng
(17)Con trỏ
xâu
▪ Ta có char tinhthanh[30] =“Da Lat”;
▪ Tương đương :
char *tinhthanh;
tinhthanh=“Da lat”;
▪ Hoặc : char *tinhthanh =“Da lat”;
▪ Ngoài thao tác xâu tương tự mảng
*(tinhthanh+3) = “l”
(18)Mảng các
con trỏ
▪ Con trỏ loại liệu nên ta tạo một mảng phần tử trỏ theo dạng thức.
<kiểu> *<mảng trỏ>[<số phần tử>];
▪ Ví dụ: char *ds[10];
▫ ds mảng gồm 10 phần tử, phần tử trỏ kiểu char, dùng để lưu trữ 10 xâu ký tự đó
▪ Cũng có thẻ khởi tạo trực tiếp giá trị khai báo
(19)▪ Cần phân biệt mảng trỏ và mảng nhiều chiều
▪ Mảng nhiều chiều mảng thực khai báo có đủ vùng nhớ dành sẵn cho phần tử
▪ Mảng trỏ dành không gian nhớ cho biến trỏ
(chứa địa chỉ) Khi khởi tạo hay gán giá trị: cần thêm nhớ cho phần tử sử dụng => tốn nhiều
(20)Mảng các
con trỏ
▪ Một ưu điểm khác mảng trỏ ta hốn chuyển đối tượng (mảng con, cấu trúc ) trỏ trỏ
bằng cách hoán chuyển trỏ
▪ Ưu điểm việc truyền tham số hàm
▪ Ví dụ: Vào danh sách lớp theo họ tên, sau xếp để in theo thứ tự ABC