Bài giảng Kỹ thuật lập trình: Bài 7 - TS. Ngô Hữu Dũng

30 5 0
Bài giảng Kỹ thuật lập trình: Bài 7 - TS. Ngô Hữu Dũng

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Bài giảng Kỹ thuật lập trình: Bài 7 do TS. Ngô Hữu Dũng biên soạn cung cấp cho người học các kiến thức: Khái niệm con trỏ, con trỏ và địa chỉ, kiểu con trỏ, phạm vi ứng dụng con trỏ, lợi hại của con trỏ, kiểu nguyên thủy, con trỏ và hằng số, con trỏ và đối số của hàm,...

Kỹ thuật lập trình Bài – Kiểu trỏ TS Ngơ Hữu Dũng 181 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Khái niệm trỏ (pointer)  Con trỏ biến mà giá trị địa nhớ  Địa nhớ?  scanf(“%d”,&i); // &i địa nhớ biến i Khai báo  type * variable_name;  Con trỏ lưu địa nhớ      182 p = 0073FB60 Biến i = 20 Địa i 0073FB60 int i = 20; p 0073FB54 int * p; // Khai báo trỏ p p = &i; // Con trỏ p gán địa biến i Ta nói trỏ p “trỏ vào” biến i Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Giá trị 20 0073FB60 Con trỏ địa int x; // Biến số nguyên x // Con trỏ p kiểu số nguyên int *p; p = &x; // p trỏ vào x x = 20; printf("%d ", x); // Giá trị x printf("%d ", *p); // Giá trị x // Địa x printf("%p ", &x); printf("%p ", p); // Địa x *p = 40; 10 printf("Gia tri: %d = %d" , *p, x); 11 printf("Dia chi: %p = %p" , p, &x); 183 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngơ Hữu Dũng Kiểu trỏ  Khai báo: Dùng dấu *   Địa biến mà trỏ trỏ vào   *p = x In hình địa chỉ: Dùng %p   p = &x Giá trị biến mà trỏ trỏ vào: Dùng dấu *   int *p; printf(“%p = %p”, p, &x); Chú ý: Phân biệt dấu * dấu & 184 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Sử dụng trỏ  Chưa trỏ vào biến    int *p; *p = 40; // Run-time error! Trỏ vào biến       185 int x, *p1, *p2; p1 = &x; // Trỏ p1 vào biến x *p1 = 40; // x = 40; p2 = p1; // gán trực tiếp, tương đương với p2 = &x; *p2 = 50; // x = 50; *p1 = 60; // x = 60; Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngơ Hữu Dũng Ví dụ vận dụng int x, y, *px, *py=NULL; px = &x; // px trỏ vào x py = &y; // py trỏ vào y *px = 10; y = 15; printf("x=%d\ny=%d\n",*px,*py); (*px)++; ++*px; *py += 5; printf("x=%d\ny=%d\n",*px,*py); 10 printf("%d+%d=%d\n",x,y,*px + *py); 11 printf("%d*%d=%d\n",x,y,*px * *py); 12 printf("&x=%p\n&y=%p\n",px,py); 186 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Phạm vi ứng dụng trỏ  Con trỏ trỏ vào liệu           187 Một kiểu nguyên thủy: int, float, char NULL (rỗng, không trỏ đến đâu) Một số Một đối số hàm Một mảng/chuỗi Một cấu trúc struct Một hàm Một trỏ khác (con trỏ trỏ vào trỏ) Một ô nhớ cấp phát động Một tập tin Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Lợi hại trỏ Có thể dùng để thao tác với loại liệu  Thuật lợi để truy cập đến cấu trúc liệu lớn  Sử dụng nhớ linh hoạt      Cấp phát / giải phóng nhớ động q trình thực thi Cấp phát nhớ mới: Hàm malloc stdlib.h Giải phóng nhớ: Hàm free stdlib.h Nếu sử dụng trỏ không cẩn thận   188 Dễ nhầm lẫn Khó tìm lỗi Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Kiểu nguyên thủy // Con trỏ trỏ vào kiểu nguyên thủy int i = 10, *pi; float f = 1.2e2, *pf; char c = 'r', *pc; pi = &i; pf = &f; pc = &c; printf("%d,%f,%c\n",*pi,*pf,*pc); // Chú ý dùng kiểu liệu // Warning! 10 pc = &f; // Warning! 11 pf = &i; // Warning! 12 pi = &c; 189 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Con trỏ rỗng - NULL  NULL giá trị đặc biệt trỏ     Không trỏ đến đâu #define NULL Được định nghĩa thư viện stdio.h Sử dụng   Khởi tạo trỏ: int *p = NULL; Kiểm tra trỏ if (p != NULL) printf(“%d”,*p);  if (p) printf(“%d”, *p);   190 Kết thúc danh sách liệu Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Mảng trỏ số (constant pointer)  Mảng trỏ số        int a[10]; int *pa; pa = a; // a trỏ, pa gán cho a, khơng cần &a pa++; // Con trỏ pa thay đổi giá trị a = pa; // ERROR! a số a++; // ERROR! a số Mảng a trỏ trỏ vào phần tử mảng thay đổi giá trị địa 196 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Truyền đối số mảng / chuỗi  Truyền đối số mảng vào hàm      void sapxep(int a[], int n) Địa phần tử mảng truyền: &a[0] Có thể thay trỏ void sapxep(int *a, int n) Tương tự với chuỗi  197 Tham số function(char s[]){…} function(char *s){…} tương đương Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngơ Hữu Dũng Ví dụ truyền đối số mảng/chuỗi int printArray(int *pa, int n) { int *pt; for (pt=pa;pt, =, =pa) // Phép so sánh { printf("%d ",*pt); pt ; // Phép toán giảm } } int stringLength(char *s) { char *p = s; // Phép gán while (*p!='\0') p++; // Phép toán tăng return p - s; // Phép trừ trỏ } Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Con trỏ chuỗi  Tương tự với mảng chuỗi có đặc điểm khác  10 201 Chuỗi kết thúc ký tự rỗng, ‘\0’ void stringCopy(char *s, char *t) { while (*t != '\0') { *s = *t; s++; t++; } *s = '\0'; // Ký tự rỗng kết thúc chuỗi } Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngơ Hữu Dũng Con trỏ chuỗi (tt) 10 11 12 13 14 202 void stringCopy1(char *s, char *t) { while ((*s = *t) != '\0'){ //Gán, so sánh s++; t++; // Tăng } } void stringCopy2(char *s, char *t) { while ((*s++ = *t++) != '\0');//Gán, so sánh, tăng } void stringCopy3(char *s, char *t) { while (*s++ = *t++); // Gán, tăng } Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Con trỏ cấu trúc 10 11 12 13 14 203 struct t_date{ int day; int month; int year; }; struct t_date today; struct t_date *ptr; ptr = &today; (*ptr).day = 15; (*ptr).month = 9; (*ptr).year = 2016; ptr->day = 15; ptr->month = 9; ptr->year = 2016; // // // // // Biến cấu trúc Con trỏ kiểu cấu trúc Trỏ vào cấu trúc Truy cập member, cách Dùng dấu ‘.’ // Truy cập member, cách // Dùng dấu ‘->’ Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngơ Hữu Dũng Con trỏ cấu trúc (2) struct t_student{ int ID; char *ten; struct t_date birth, *pB; }; struct t_student SV, *pSV; pSV = &SV; // // pSV->ID = 123; pSV->ten = "Nguyen Van A";// 10 pSV->birth.day = 16; // // 11 pSV->pB = &SV.birth; // 12 pSV->pB->month = 4; 13 (*pSV->pB).year = 1996; // 204 Trỏ vào cấu trúc t_stu… SV.ID SV.ten SV.birth.day Trỏ vào cấu trúc t_date SV.birth.month SV.birth.year Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngơ Hữu Dũng Con trỏ cấu trúc (3) ++pSV->ID; // Tăng giá trị ID printf("%d ",pSV->ID); printf("%c",*pSV->ten); //Ký tự ‘N’ printf("%c",pSV->ten[1]); //Ký tự thứ ‘g’ //Từ ký tự ‘u’->hết printf("%s ",pSV->ten+2); printf("%d ",++pSV->pB->day); //Tăng day printf("%d ",(*pSV->pB).month); printf("%d\n",SV.pB->year); while(*pSV->ten!='\0') printf("%c",*pSV->ten++); 10 // !? Chuỗi rỗng !? 11 printf("\n%s",pSV->ten); 12 printf("%s", pSV->ten); // !? 205 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Con trỏ hàm  Hàm trả kiểu trỏ  206 Đối số kiểu trỏ char * stringCopy4(char *s, char *t) { int count = 0; count++; while (*s++ = *t++); return s-count; } Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngơ Hữu Dũng Con trỏ đến trỏ  Con trỏ chứa địa trỏ khác       207 char x; char * y; char ** z; x = 'x'; y = &x; z = &y; x x x 'x' 00000078 00AFF75F 00000078 00AFF75F 00AFF750 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ngô Hữu Dũng Con trỏ cấp phát động  Con trỏ cấp phát nhớ   208 Trỏ trực tiếp vào nhớ động Không cần thông qua biến cụ thể #include int n ,*a , i; scanf("%d", &n); a =(int*)malloc(sizeof(int)*n); // Cấp phát nhớ for(i=0;iID); printf("%c",*pSV->ten); //Ký tự ‘N’ printf("%c",pSV->ten[1]);... printf("%c",*pSV->ten++); 10 // !? Chuỗi rỗng !? 11 printf(" %s",pSV->ten); 12 printf("%s", pSV->ten); // !? 205 Kỹ thuật lập trình | DHTH11C | HK1 | 201 6-2 0 17 Ngô Hữu Dũng Con trỏ hàm  Hàm trả kiểu trỏ  206 Đối

Ngày đăng: 08/05/2021, 11:41

Tài liệu cùng người dùng

Tài liệu liên quan