Chương 7 - Con trỏ. Chương này gồm có các nội dung: Địa chỉ và con trỏ; con trỏ, mảng và xâu ký tự; quản lý bộ nhớ với hàm malloc() và free(); bài tập chương 7. Mời các bạn cùng tham khảo để biết thêm các nội dung chi tiết.
Chương Con trỏ I Địa trỏ II Con trỏ, mảng xâu ký tự III Quản lý nhớ với hàm malloc() free() IV Bài tập chương Lập trình nâng cao - Chương 07 - Ngô Công Thắng I Địa trỏ Địa (hằng trỏ) Toán tử địa & Khai báo biến trỏ Truy nhập biến qua trỏ Con trỏ void trỏ NULL Các phép toán trỏ Con trỏ trỏ tới trỏ Lập trình nâng cao - Chương 07 - Ngô Công Thắng Địa (hằng trỏ) ² Mỗi byte nhớ máy tính có địa Các địa số trở Ví dụ có MB nhớ địa thấp địa cao 1.048.575 ² Bất kỳ chương trình nạp vào nhớ chiếm khoảng địa Điều có nghĩa biến hàm chương trình bắt đầu địa cụ thể Hình 7.1 cho thấy địa nhớ Lập trình nâng cao - Chương 07 - Ngơ Công Thắng Địa (hằng trỏ) tiếp Hình 7.1 Địa nhớ 655.359 chương trình 314.810 314.809 314.808 314.807 314.806 314.805 314.804 314.803 314.802 314.801 314.800 314.799 var1 int var2 char var3 float var4 int var1 có địa 314.809 var2 có địa 314.808 var3 có địa 314.804 var4 có địa 314.802 Lập trình nâng cao - Chương 07 - Ngơ Cơng Thắng Toán tử địa & ²Toán tử địa ký hiệu &, dùng để lấy địa biến Toán tử & phải đặt trước tên biến muốn lấy địa Ví dụ: Chương trình sau đưa địa biến nguyên a, b, c Lập trình nâng cao - Chương 07 - Ngô Công Thắng Khai báo biến trỏ ² Vì địa nhớ số nên lưu trữ biến giống giá trị kiểu int, char float Một biến mà chứa giá trị địa gọi biến trỏ hay gọi tắt trỏ Nếu trỏ chứa địa biến ta nói trỏ trỏ tới biến ² Để khai báo biến trỏ ta dùng cú pháp sau: Kiểu* Tên_biến_con_trỏ; Kiểu kiểu liệu đối tượng mà biến trỏ trỏ tới Dấu * có nghĩa trỏ tới Nên để dấu * bên cạnh tên kiểu để nhấn mạnh phần kiểu khơng phải tên biến trỏ Lập trình nâng cao - Chương 07 - Ngô Công Thắng Khai báo biến trỏ (tiếp) ² Ví dụ: int a; int* ptr; ptr = &a; Lệnh khai báo biến trỏ có tên ptr trỏ tới số nguyên int Nói cách khác trỏ ptr chứa địa biến nguyên ² Để khai báo nhiều biến trỏ trỏ tới kiểu liệu ta viết: Kiểu *Biến1, *Biến2, *Biến3,…; Mặc dù dấu * để cạnh tên biến trỏ nên hiểu phần kiểu Ví dụ: int *p, *q; Lập trình nâng cao - Chương 07 - Ngô Công Thắng Khai báo biến trỏ (tiếp) ² Khi khai báo biến trỏ biến trỏ chứa giá trị vô nghĩa (trừ khởi tạo) Giá trị vô nghĩa địa nhớ nằm phần chương trình ta hệ điều hành Điều nguy hiểm ta đưa giá trị vào ô nhớ trỏ trỏ tới Bởi vậy, trước sử dụng trỏ ta phải đưa địa vào ² Con trỏ trỏ tới kiểu chứa địa biến kiểu Khơng thể gán địa biến float tới trỏ trỏ tới int Lập trình nâng cao - Chương 07 - Ngô Công Thắng Truy nhập biến qua trỏ ² Một câu hỏi đặt tên biến mà biết địa có truy nhập vào biến khơng? Câu trả lời có Con trỏ chứa địa biến nên ta truy nhập biến qua trỏ ² Để truy nhập tới biến trỏ ptr trỏ tới ta dùng toán tử truy nhập gián tiếp * đặt trước tên biến trỏ: *ptr *ptr tương đương với tên biến, chỗ dùng tên biến chỗ dùng *ptr Lập trình nâng cao - Chương 07 - Ngơ Công Thắng Truy nhập biến qua trỏ ² Toán tử truy nhập gián tiếp ký hiệu * có nghĩa giá trị biến trỏ tới biến trỏ nằm bên phải nó, khác với dấu * khai báo biến trỏ có nghĩa trỏ tới p ² Ví dụ: int v; //Khai báo biến có kiểu int v int* p; //Khai báo biến trỏ p trỏ tới int p = &v; //Gán địa biến v cho trỏ p v = 3; //Gán vào v *p = 3; //Gán vào v gián tiếp qua trỏ p Lập trình nâng cao - Chương 07 - Ngơ Cơng Thắng 10 Các biến ngồi (tiếp) Ví dụ 2: Hạn chế việc truy nhập biến //Bat dau file static int a; //dinh nghia bien ngoai a //bien a chi truy nhap duoc file //Cuoi file //Bat dau file extern int a; //Khong dung duoc khai bao //Cuoi file Lập trình nâng cao - Chương 07 - Ngơ Cơng Thắng 42 Các biến ngồi (tiếp) ² Có hai vấn đề sử dụng biến ngồi: n n Vì biến ngồi truy nhập từ hàm chương trình nên dễ bị thay đổi làm liệu Vì biến ngồi có phạm vi hoạt động nơi chương trình nên ta phải quan tâm đến vấn đề kiểm soát tên biến để cho khơng có hai biến trùng tên Lập trình nâng cao - Chương 07 - Ngơ Cơng Thắng 43 Các biến tĩnh cục (local static) ² Các biến tĩnh cục sử dụng ta muốn trì giá trị biến khai báo hàm lời gọi hàm Tức hàm kết thúc biến tĩnh vẫn chứa giá trị, hàm gọi lần lại sử dụng giá trị Phạm vi hoạt động biến tĩnh cục hàm thời gian tồn suốt thời gian chương trình chạy Lập trình nâng cao - Chương 07 - Ngô Công Thắng 44 Hạn chế việc lưu trữ mảng ² Mảng hay sử dụng cần lưu trữ số lượng lớn biến hay đối tượng Tuy nhiên thời điểm viết chương trình ta phải xác định kích thước mảng khơng đợi đến chương trình thực Đoạn chương trình sau sinh lỗi: printf(“Nhap vao kich thuoc mang: ”);scanf(“%i”,&size); int a[size]; //Lỗi, kích thước mảng phải ² Trong nhiều trường hợp, thời điểm viết chương trình ta khơng biết cần nhớ Nếu dự trù nhiều mà không dùng hết lãng phí nhớ, dự trù mà cần lưu trữ nhiều khơng có chỗ chứa Vấn đề khắc phục chế cấp phát động nhớ hàm malloc() free() Lập trình nâng cao - Chương 07 - Ngô Công Thắng 45 Hàm malloc() free() ² Trong C có hàm thực chức cấp phát giải phóng nhớ, hàm malloc() free() Muốn sử dụng hai hàm chương trình ta phải khai báo sử dụng thư viện stdlib (#include) ² Cú pháp cấp phát nhớ động (1 biến) sau: Biến_con_trỏ = (Kiểu_dl_của_biến*) malloc(sizeof(Kiểu_dl_của_biến)); Biến trỏ phải khai báo trỏ đến kiểu liệu biến Ví dụ: int* p=NULL; p = (int*) malloc(sizeof(int)); Lập trình nâng cao - Chương 07 - Ngô Công Thắng 46 Hàm malloc() free() ² Hàm malloc() cấp phát ô nhớ phần nhớ Heap chương trình chạy, đủ để chứa giá trị có kiểu Kiểu_dl_của_biến trả trỏ trỏ tới ² Vì kích thước phần Heap có giới hạn nên hết Nếu phần nhớ Heap hết mà ta cấp phát hàm malloc() trả trỏ rỗng (NULL) Bởi vậy, luôn phải kiểm tra trỏ trả hàm malloc() trước dùng if(!Biến_con_trỏ) printf(“Cap phat bo nho bi loi!”); Lập trình nâng cao - Chương 07 - Ngô Công Thắng 47 Hàm malloc() free() (tiếp) ² Cú pháp giải phóng nhớ cấp phát hàm malloc() free(p); Trong p trỏ trỏ tới vùng nhớ cấp phát động hàm malloc() ² Hàm free(p) giải phóng vùng nhớ trỏ tới biến trỏ p Chỉ nên dùng hàm free() để giải phóng vùng nhớ cấp phát hàm malloc(), calloc() realloc() Lập trình nâng cao - Chương 07 - Ngô Công Thắng 48 Hàm malloc() free() (tiếp) ² Ví dụ sử dụng hàm malloc() free(): //Khai bao su dung thu vien chuong trinh #include #include int main() { int* p; p = (int*) malloc(sizeof(int)); //cap phat bo nho chua kieu int if(p != NULL) { printf("Cap phat bo nho bi loi“); return 1; } *p=100; //Gan 100 vao o nho vua duoc cap printf(”*p = %i”,*p); //Hien thi noi dung cua o nho vua duoc cap free(p); //Giai phong o nho vua duoc cap return 0; } Lập trình nâng cao - Chương 07 - Ngô Công Thắng 49 Cấp phát mảng động với calloc() ² Với chế cấp phát động nhớ ta cấp phát nhớ cho biến mảng Điều cho phép xác định số phần tử mảng chạy chương trình Để cấp phát động cho mảng chiều ta dùng hàm calloc() với cú pháp sau: Biến_con_trỏ = (KPT*) calloc(size, sizeof(KPT)); KTP kiểu phần tử, size số phần tử mảng size hằng, biến biểu thức int a[100]; int *a = (int*) calloc(100,sizeof(int)); a[0]=25; a[1]=15; ² Để giải phóng vùng nhớ cấp phát cho mảng ta dùng hàm free() với đối số Biến trỏ trỏ tới mảng: free(Biến_con_trỏ); Lập trình nâng cao - Chương 07 - Ngơ Cơng Thắng 50 Ví dụ Nhập vào dãy số ngun có n phần tử Tìm vị trí phần tử có giá trị lớn Y/c sử dụng mảng động để chứa dãy số Lập trình nâng cao - Chương 07 - Ngô Công Thắng 51 Mảng động (tiếp) ² Với mảng động ta thay đổi kích thước mảng mà giữ nội dung mảng ban đầu ² Để thay đổi kích thước mảng động ta dùng hàm realloc() với cú pháp sau: p = (KPT*) realloc(p, size_new*sizeof(KPT)); Trong KPT kiểu phần tử, p trỏ trỏ tới mảng động, size_new kích thước mảng động Nếu thay đổi kích thước khơng thành cơng, hàm realloc() trả trỏ rỗng (NULL) Lập trình nâng cao - Chương 07 - Ngơ Cơng Thắng 52 Ví dụ Nhập vào dãy số nguyên có n phần tử Chèn thêm phần tử x vào cuối dãy Yêu cầu sử dụng mảng động chứa dãy số Lập trình nâng cao - Chương 07 - Ngô Công Thắng 53 Mảng động (tiếp) ² Ví dụ mảng động: //Khai bao su dung thu vien chuong trinh #include #include int main() { int* a; int n,i; printf("Nhap vao so phan tu cua mang: ");scanf("%i",&n); a = (int*) calloc(n, sizeof(int));//Cap phat bo nho cho mang n phan tu nguyen if(!a) { printf("Cap phat bo nho bi loi"); return 1; } //Tiếp trang sau Lập trình nâng cao - Chương 07 - Ngơ Cơng Thắng 54 Mảng động (tiếp) ² Ví dụ mảng động: (tiếp) //Nhap cac gia tri vao mang printf("Nhap vao mang so nguyen:\n" ); for(i=0;i