Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
19,87 MB
Nội dung
Chương KIỂU CON TRỎ Lê Quý Tài quytai3985@gmail.com Hà Nội – 2012 Nội dung 24/03/2018 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 24/03/2018 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 24/03/2018 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 24/03/2018 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: Môi trường MD-DOS (16 bit): bytes Môi trường Windows (32 bit): bytes 24/03/2018 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 24/03/2018 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; 24/03/2018 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 24/03/2018 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 q=p; Ví dụ: float a,*p,*q; p=&a; 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 24/03/2018 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!”); 24/03/2018 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); int kq2 = tinhtoan(1, 2); 24/03/2018 Chương 6-Kiểu trỏ // Chính quy // Ngắn gọn 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); } 24/03/2018 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); } 24/03/2018 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); } 24/03/2018 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); PhepToan array2[2]; // tường minh // 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)); } 24/03/2018 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 int (*PhepToan)(int x, int y); int *PhepToan(int x, int y); Có thể bỏ tên biến tham số khai báo trỏ hàm int (*PhepToan)(int x, int y); int (*PhepToan)(int, int); 24/03/2018 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: 24/03/2018 Đượ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 Cấp void Cấp *malloc(Số ô nhớ cần cấp phát) phát vùng nhớ có kích thước *calloc(n,sizeof(object)) 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 24/03/2018 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*/ 24/03/2018 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); 24/03/2018 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; } 24/03/2018 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