Bài giảng Kiến trúc máy tính - Chương 5: Con trỏ - Nguyễn Đức Minh
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Kiến trúc máy tính - Chương 5: Con trỏ - Nguyễn Đức Minh", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- bai_giang_kien_truc_may_tinh_chuong_5_con_tro_nguyen_duc_min.pptx
Nội dung text: Bài giảng Kiến trúc máy tính - Chương 5: Con trỏ - Nguyễn Đức Minh
- Chương 5: con trỏ (pointer) 8/22/2021 1
- Agenda Khái niệm về con trỏ Toán tử con trỏ Thao tác trên con trỏ Con trỏ void Con trỏ null Mảng con trỏ Cấp phát bộ nhớ động 8/22/2021 2
- 1. Khái niệm về con trỏ Con trỏ là 1 biến chứa 1 địa chỉ bộ nhớ. Địa chỉ này là vị trí của 1 đối tượng khác (thường là 1 biến) trong bộ nhớ. 8/22/2021 3
- 1. Khái niệm về con trỏ Giống như tất cả các biến, con trỏ phải được khai báo trước khi sử dụng. Dạng tổng quát để khai báo 1 biến con trỏ: type *pointerName; ◦ type: Kiểu dữ liệu của biến mà con trỏ trỏ đến Ví dụ: int *countPtr, count; 8/22/2021 4
- 2. Toán tử con trỏ (pointer operation) Có 2 toán tử con trỏ là * và & Toán tử &: là toán tử 1 ngôi trả về địa chỉ bộ nhớ của toán hạng của nó. Cú pháp: &variableName Ví dụ: int y = 50; // Khai báo biến y int *yPtr; // Khai báo con trỏ yPtr yPtr = &y; // gán địa chỉ của y cho yPtr 8/22/2021 5
- 2. Toán tử con trỏ (pointer operation) int y = 50; int *yPtr; yPtr = &y; ➔ yPtr = ??? 8/22/2021 6
- 2. Toán tử con trỏ (pointer operation) Toán tử * : là toán tử một ngôi trả về giá trị tại địa chỉ con trỏ trỏ đến Cú pháp: *pointerName Ví dụ: int y = 50; // Khai báo biến y int *yPtr; // Khai báo con trỏ yPtr cout << *yPtr; // in ra giá trị của biến y – biến mà con trỏ yPtr đang trỏ đến 8/22/2021 7
- 2. Toán tử con trỏ (pointer operation) Ví dụ 1: #include int main() { int a; int *aPtr; // aPtr is an int * pointer to an integer a = 7; aPtr = &a; cout << endl << &a << endl << aPtr; cout << endl << a << endl << *aPtr; cout << "\n&*aPtr = " << &*aPtr << "\n*&aPtr = " << *&aPtr << endl; return 0; } // end main 8/22/2021 8
- 2. Toán tử con trỏ (pointer operation) Ví dụ 2: #include int main () { int firstvalue, secondvalue; int * mypointer; mypointer = &firstvalue; *mypointer = 20; mypointer = &secondvalue; *mypointer = 10; cout << “1st value is " << firstvalue; cout << “2nd value is " << secondvalue ; return 0; } 8/22/2021 9
- 2. Toán tử con trỏ (pointer operation) Ví dụ 3: #include void main () { int firstvalue = 5, secondvalue = 15; int * p1, * p2; p1 = &firstvalue; p2 = &secondvalue; *p1 = 10;// value pointed by p1 = 10 *p2 = *p1; p1 = p2; //value of pointer is copied *p1 = 20; // value pointed by p1 = 20 cout << "firstvalue is " << firstvalue ; cout << "secondvalue is " << secondvalue ; } 8/22/2021 10
- 3. Các thao tác trên con trỏ Lệnh gán con trỏ: dùng phép gán để gán giá trị của một con trỏ cho một con trỏ khác có cùng kiểu Ví dụ: int x; int *p1, *p2; p1 = &x; p2 = p1; Sau khi đọan lệnh trên được thực hiện, cả hai p1 và p2 cùng trỏ đến biến x. 8/22/2021 11
- 3. Các thao tác trên con trỏ Phép toán số học trên con trỏ: Chỉ có 2 phép toán sử dụng trên con trỏ là phép cộng và phép trừ. 8/22/2021 12
- 3. Các thao tác trên con trỏ Tất cả con trỏ sẽ tăng hay giảm với đơn vị là kích thước của kiểu dữ liệu của nó. char *ch; int *i; ch = ch + 3; ➔ ch = ??? i = i + 2; ➔ i = ??? 8/22/2021 13
- 3. Các thao tác trên con trỏ Ví dụ : ◦ char *a; ◦ short *b; ◦ long *c; Các con trỏ a, b, c lần lượt trỏ tới ô nhớ 1000, 2000 và 3000. Cộng các con trỏ với một số nguyên: ◦ a = a + 1; //con trỏ a dời đi ? byte ◦ b = b + 1;//con trỏ b dời đi ? byte ◦ c = c + 1; //con trỏ c dời đi ? byte 8/22/2021 14
- 4. con trỏ Void (void pointer ) Ví dụ: int a, *pa; float f, *pf; pa = &a; // hợp lệ pf = &f; // hợp lệ pa = &f; // không hợp lệ vì pa là con trỏ kiểu int nên chỉ chứa địa chỉ của biến kiểu int pf = &a; //không hợp lệ vì pf là con trỏ kiểu float nên chỉ chứa địa chỉ của biến kiểu float 8/22/2021 15
- 4. con trỏ Void (void pointer) Con trỏ void là một lọai con trỏ đặc biệt mà có thể trỏ đến bất kỳ kiểu dữ liệu nào. Cú pháp: void *pointerVariable; Ví dụ: void *p; p = &a; // con trỏ p trỏ đến biến nguyên a p = &f; // con trỏ p trỏ đến biến thực f 8/22/2021 16
- 4. con trỏ Void (void pointer) Tùy thuộc con trỏ void đang trỏ đến kiểu dữ liệu nào, ta phải ép về đúng kiểu tương ứng khi dùng trong các biểu thức Ví dụ: Nếu p đang trỏ đến biến nguyên a, để tăng giá trị của biến a lên 10 ta phải dùng lệnh sau: *(int*)p + 10; Nếu p đang trỏ đến biến thực f, để tăng giá trị của biến f lên 10 ta phải dủng lệnh sau: *(float*)p + 10; 8/22/2021 17
- 5. Mảng & con trỏ Giữa mảng và con trỏ có 1 mối quan hệ tương quan. Tên của 1 mảng có thể được xem như là 1 con trỏ. ◦ int b[ 5 ]; // khai báo 1 mảng kiểu int 5 phần tử ◦ int *bPtr; // khai báo 1 con trỏ trỏ đến kiểu int Tên của một mảng tương ứng 1 con trỏ trỏ đến phần tử đầu tiên trong mảng. ◦ bPtr = b; // gán địa chỉ của mảng b cho con trỏ bPtr Câu lệnh trên tương đương với ◦ bPtr = &b[0]; Để tham chiếu phần tử thứ 3 trong mảng b,ta dùng một trong 2 cách sau ◦ b[ 2 ] ◦ *(bPtr + 2) 8/22/2021 18
- 5. Mảng con trỏ #include #include void main () { int numbers[5], * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", "; } 8/22/2021 19
- 5. con trỏ null (null pointer ) Một con trỏ hiện hành không trỏ đến một địa chỉ bộ nhớ hợp lệ thì được gán giá trị NULL. Nói các khác, con trỏ NULL là con trỏ không trỏ đến đâu cả. NULL được định nghĩa trong Ví dụ: #include void main() { int* p; cout <<“Gia tri con tro p tro den la: “<< *p; } Kết quả của chương trình trên là: NULL POINTER ASSIGNMENT 8/22/2021 20
- 6. Cấp phát vùng nhớ động Cấp phát động là phương tiện nhờ đó chương trình có thể dành thêm bộ nhớ trong lúc đang thực thi. Cấp phát động trong C++ ◦ C++ cung cấp 2 toán tử dùng trong việc cấp phát và thu hồi bộ nhớ là new và delete 8/22/2021 21
- 6. Cấp phát vùng nhớ động Toán tử new: cấp phát bộ nhớ và trả về 1 con trỏ đến byte đầu tiên trong vùng nhớ được cấp phát ◦ Cú pháp pointerName = new datatype; ◦ datatype : Kiểu dữ liệu của con trỏ pointer Toán tử delete: Thu hồi vùng nhớ được cấp phát trước đó bởi toán tử new ◦ Cú pháp pointerName = delete; 8/22/2021 22
- 6. Cấp phát vùng nhớ động Ví dụ: #include #include int main() { int *p; p = new int; // allocate space for an int *p = 100; cout << "At " << p << " "; cout << "is the value " << *p << "\n"; delete p; return 0; } 8/22/2021 23
- 7. Mảng con trỏ Mỗi biến con trỏ là một biến đơn. Ta có thể tạo mảng của các con trỏ với mỗi phần tử của mảng là một con trỏ. Cú pháp: type *pointerArray[elements]; ◦ type: kiểu dữ liệu mà các con trỏ phần tử trỏ đến. ◦ pointerArray: tên mảng con trỏ. ◦ elements: số phần tử của mảng con trỏ 8/22/2021 24
- 7. Mảng con trỏ int *p[5]; int a=6; p[0] = &a; p[2] = p[0]; int b; b = *p[0]; 8/22/2021 25