Slide cslt1 - le_cam_tu_hvnh ď C06-Kieu con tro tài liệu, giáo án, bài giảng , luận văn, luận án, đồ án, bài tập lớn về...
Chương KIỂU CON TRỎ Lê Quý Tài quytai3985@gmail.com Hà Nội – 2012 Nội dung 12/12/17 Con trỏ địa Khai báo trỏ Con trỏ mảng chiều Con trỏ mảng nhiều chiều Mảng trỏ Con trỏ hàm Cấp phát nhớ động Chương 6-Kiểu trỏ Con trỏ địa Ví dụ: float a=10.12; Xác định biến có tên a có kiểu float có giá trị 10.12 Máy cấp phát cho x vùng nhớ gồm byte liên tiếp Địa biến số thứ tự byte Có nhiều kiểu địa khác tương ứng với kiểu biến khác 12/12/17 Chương 6-Kiểu trỏ 3/50 Con trỏ địa Con trỏ biến dùng để chứa địa Có nhiều kiểu trỏ tương ứng với nhiều loại địa Ví dụ: Con trỏ kiểu int chứa địa biến kiểu int… *a giá trị lưu nhớ có địa a &a địa nhớ chứa giá trị a 12/12/17 Chương 6-Kiểu trỏ 4/50 Khai báo trỏ Khai báo trực tiếp *; Trong đó: * tốn tử trỏ Ví dụ: int *p1,m,n; p1=&n; *p1=10; /* ô nhớ trỏ p1 trỏ đến gán giá trị 10 */ Chú ý: Khi gán địa biến cho biến trỏ, thay đổi nội dung ô nhớ trỏ tới làm giá trị biến thay đổi theo 12/12/17 Ví dụ: int *p2,a=10; p2=&a; *p2=*p2+3; Khi a có giá trị 13 Chương 6-Kiểu trỏ 5/50 Khai báo trỏ (tt) Khai báo gián tiếp typedef *; ; Ví dụ typedef int *pint; int *p1; pint p2, p3; Kích thước trỏ Con trỏ lưu địa nên kích thước trỏ nhau: 12/12/17 Môi trường MD-DOS (16 bit): bytes Môi trường Windows (32 bit): bytes Chương 6-Kiểu trỏ 6/50 Con trỏ NULL Khái niệm int int int int Con trỏ NULL trỏ không trỏ đâu Khác với trỏ chưa khởi tạo n; *p1 = &n; *p2; // unreferenced local varialbe *p3 = NULL; NULL 12/12/17 Chương 6-Kiểu trỏ 7/50 Khởi tạo kiểu trỏ Khởi tạo = &; Khi khai báo, biến trỏ đặt địa (khơng biết trước) chứa giá trị không xác định trỏ đến vùng nhớ trước Đặt địa biến vào trỏ (tốn tử &) Ví dụ int a, b; int *pa = &a, *pb; pb = &b; 12/12/17 Chương 6-Kiểu trỏ 8/50 Sử dụng trỏ Truy xuất đến ô nhớ mà trỏ trỏ đến Con trỏ chứa số nguyên địa Sử dụng toán tử * Ví dụ int n=10; int *p; printf("\nDia chi printf("\nGia tri p=&n; //Con tro p printf("\nDia chi printf("\nGia tri printf("\nGia tri 12/12/17 cua n: %p",&n); cua n: %d",n); tro toi n cua tro: %p",&p); cua tro: %p",p); duoc tro toi la: %d",*p); Chương 6-Kiểu trỏ 9/50 Sử dụng trỏ (tt) Sử dụng tên trỏ Giá trị trỏ (địa biến) sử dụng biểu thức Nếu tên trỏ bên trái tốn tử gán giá trị biểu thức bên phải phải địa Ví dụ: float a,*p,*q; p=&a; q=p; Kết trỏ q chứa địa biến a Sử dụng dạng khai báo Ví dụ: float x,*px; px=&x; //px trỏ tới x 12/12/17 Nếu trỏ px trỏ tới biến x cách viết x *px tương đương ngữ cảnh Chương 6-Kiểu trỏ 10/50 Con trỏ hàm (tt) So sánh trỏ hàm if { (tinhtoan != NULL) if (tinhtoan == &Cong) printf(“Con trỏ đến hàm Cong.”); else if (tinhtoan == &Tru) printf(“Con trỏ đến hàm Tru.”); else printf(“Con trỏ đến hàm khác.”); } else printf(“Con trỏ chưa khởi tạo!”); 12/12/17 Chương 6-Kiểu trỏ 36/50 Con trỏ hàm (tt) Gọi hàm thông qua trỏ hàm Sử dụng tốn tử lấy nội dung “*” (chính quy) trường hợp bỏ int Cong(int x, int y); int Tru(int x, int y); int (*tinhtoan)(int, int); tinhtoan = Cong; int kq1 = (*tinhtoan)(1, 2); // Chính quy int kq2 = tinhtoan(1, 2); // Ngắn gọn 12/12/17 Chương 6-Kiểu trỏ 37/50 Con trỏ hàm (tt) Truyền tham số trỏ hàm int Cong(int x, int y); int Tru(int x, int y); int TinhToan(int x, int y, int (*pheptoan)(int, int)) { int kq = (*pheptoan)(x, y); // Gọi hàm return kq; } main() { int (*pheptoan)(int, int) = &Cong; int kq1 = TinhToan(1, 2, pheptoan); int kq2 = TinhToan(1, 2, &Tru); } 12/12/17 Chương 6-Kiểu trỏ 38/50 Con trỏ hàm (tt) Trả trỏ hàm int (*LayPhepToan(char code))(int, int) { if (code == ‘+’) return &Cong; return &Tru; } main() { int (*pheptoan)(int, int) = NULL; pheptoan = LayPhepToan(‘+’); int kq2 = pheptoan(1, 2, &Tru); } 12/12/17 Chương 6-Kiểu trỏ 39/50 Con trỏ hàm (tt) Trả trỏ hàm (khai báo kiểu) typedef (*PhepToan)(int, int); PhepToan LayPhepToan(char code) { if (code == ‘+’) return &Cong; return &Tru; } main() { PhepToan pheptoan = NULL; pheptoan = LayPhepToan(‘+’); int kq2 = pheptoan(1, 2, &Tru); } 12/12/17 Chương 6-Kiểu trỏ 40/50 Con trỏ hàm (tt) Mảng trỏ hàm typedef (*PhepToan)(int, int); main() { int (*array1[2])(int, int); // tường minh PhepToan array2[2]; // kô tường minh array1[0] = array2[1] = &Cong; array1[1] = array2[0] = &Tru; printf(“%d\n”, printf(“%d\n”, printf(“%d\n”, printf(“%d\n”, (*array1[0])(1, 2)); array1[1](1, 2)); array2[0](1, 2)); array2[1](1, 2)); } 12/12/17 Chương 6-Kiểu trỏ 41/50 Con trỏ hàm (tt) Lưu ý Không quên dấu () khai báo trỏ hàm Có thể bỏ tên biến tham số khai báo trỏ hàm 12/12/17 int (*PhepToan)(int x, int y); int *PhepToan(int x, int y); int (*PhepToan)(int x, int y); int (*PhepToan)(int, int); Chương 6-Kiểu trỏ 42/50 Cấp phát nhớ động Biến tĩnh: Ví dụ: int, float, mảng… Là biến xác định mô tả kiểu, địa biến xác định thực chương trình; Thời gian tồn với thời gian tồn khối chương trình chứa khai báo Biến động: 12/12/17 Được tạo lúc chạy chương trình theo yêu cầu Biến động khơng có tên Truy nhập thơng qua biến trỏ (là biến tĩnh, chứa địa biến động) Chương 6-Kiểu trỏ 43/50 Cấp phát nhớ động Cấp phát nhớ (trong thư viện stdlib.h,alloc.h) void *malloc(Số ô nhớ cần cấp phát) Cấp phát vùng nhớ có kích thước void *calloc(n,sizeof(object)) Cấp phát vùng nhớ có kích thước n*sizeof(object) Dùng cấp phát nhớ cho kiểu liệu khơng phải kiểu sở Ví dụ: int a, *pa, *pb; pa = (int*)malloc(sizeof(int)); pb= (int*)calloc(10, sizeof(int)); Lưu ý: Khi sử dụng hàm malloc() hay calloc(), ta phải ép kiểu nguyên mẫu hàm trả trỏ kiểu void 12/12/17 Chương 6-Kiểu trỏ 44/50 Cấp phát nhớ động (tt) Cấp phát lại vùng nhớ cho biến trỏ void *realloc(void *poiter, kích thước mới) Ý nghĩa: Cấp phát lại vùng nhớ cho trỏ pointer quản lý, vùng nhớ có kích thước kích thước ra; cấp phát lại nội dung vùng nhớ trước tồn Kết trả hàm địa vùng nhớ Địa khác với địa cấp phát ban đầu Ví dụ: int a, *pa; pa=(int*)malloc(sizeof(int)); pa = realloc(pa, 6); /* Cấp phát lại vùng nhớ có kích thước byte*/ 12/12/17 Chương 6-Kiểu trỏ 45/50 Cấp phát nhớ động (tt) Giải phóng vùng nhớ cấp phát void free(void *pointer) Ý nghĩa: Giải phóng vùng nhớ quản lý trỏ pointer Ví dụ: Ở ví dụ trên, sau thực xong, ta giải phóng vùng nhớ cho biến trỏ pa pb: free(pa); free(pb); 12/12/17 Chương 6-Kiểu trỏ 46/50 Ví dụ cấp phát nhớ động Nhập từ bàn phím số nguyên n, đưa hình n số nguyên tố int ngto(long a) { //Kiem tra so nguyen to } int main() { long *prime=NULL, x=0; int i=0, found=0, n=0,j; printf("Ban muon tim bao nhieu so nguyen to? "); scanf("%d",&n); prime=(long *)malloc(n*sizeof(long)); if (prime==NULL) { printf("Khong du bo nho!"); return 0; } 12/12/17 Chương 6-Kiểu trỏ 47/50 Ví dụ cấp phát nhớ động (tt) *prime=2; //Cac so nguyen to dau tien da biet *(prime+1)=3; *(prime+2)=5; x=5; j=3; { x+=2; //Gia tri tiep theo de kiem tra if (ngto(x)) { *(prime+j)=x; j++; } } while (j