1 / 31

Chương 5 CON TRỎ (Pointer)

Chương 5 CON TRỎ (Pointer). 1. Khái niệm. Một con trỏ là một biến chứa địa chỉ ô nhớ . Địa chỉ này là vị trí của một đối tượng khác trong bộ nhớ . Ví du: f loat x; //x là một biến có kiểu float x=12.5; //x có giá trị là 12.5

blaise
Download Presentation

Chương 5 CON TRỎ (Pointer)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chương 5 CON TRỎ (Pointer)

  2. 1. Khái niệm Một con trỏlàmộtbiếnchứađịachỉ ô nhớ. Địachỉnàylàvịtrícủamộtđốitượngkháctrongbộnhớ. Ví du: float x; //x làmộtbiếncókiểufloat x=12.5; //x cógiátrịlà 12.5 Vàlúcnày, biến x chiếm 4 ô nhớliêntiếp, giảsửmỗi ô nhớcókíchthước 1 byte.

  3. Địa chỉ của ô nhớ • Địachỉcủa ô nhớlàsốthứtựcủa byte đầutiêntrongmộtdãycác byte liêntiếp. Địachỉnàyđượctính ở hệđếm 16. • Vídụ : • int a[4]; • Mỗibiếnkiểuintchiếm2 bytes, nhưvậybộnhớsẽdành8 ô nhớchobiến a. • Vàcáchđánhđịachỉnhưsau: giảsửđịachỉcủabiếna[0] làffee

  4. 2. Con trỏ • Con trỏlàmộtkiểudữliệuđặtbiệtdùngđểquảnlýđịachỉcủacác ô nhớ. • Con trỏkiểu<T> chỉđượcdùngđểchứađịachỉcủabiếnkiểu<T>; nghĩalà con trỏkiểuintchỉđượcdùngđểchứađịachỉcủabiếnkiểuint, con trỏkiểufloatchỉđượcdùngđểchứađịachỉcủabiếnkiểufloat. • Cáchkhaibáonhưsau: <type>* <PointerName>; Vídụ: int*pi; • Cóthểkhaibáo con trỏnhiềucấp, vídụ: int * *ppi; float * * *pppf; px int

  5. Phéplấyđịachỉcủamộtbiến • Kíhiệu: & • Cáchsửdụng:&<VarName> • Vídụ: int *pi=&a; // pi giữđịachỉcủacácbiếnnguyên a • Lưu ý: Trongtrườnghợptrên, pi làmộtđịachỉcógiátrịđịachỉlà &a, và &pi cũnglàmộtđịachỉnhưnggiátrịđịachỉnàykhôngphảilà &a màlànơighi nhận giá trị &a, khi đó: int **ppi=&pi; // con trỏ 2 cấp

  6. Phéptoánlấygiátrịtạimộtđịachỉmàmột con trỏđangtrỏtới • Kí hiệu: * • Cách sử dụng: *<PointerName> • Ví dụ: int a= 10; // biến a cógiátrị 10 int *pi; pi =&a; //pi giữđịachỉcủabiến a • *pi là giá trị của a bà bằng 10

  7. Ví dụ 1 a x 25 25 int a=25, x; y int *y; x=a; y • y=&a;

  8. Ví dụ 2 int a, *p; a=25; p=&a; m=*p ; Cho biết Giá trị của m ?

  9. Phép toán lấy thành phần của cấu trúc với con trỏ • Kíhiệu: -> • Cáchsửdụng: <Struct_Pointer_Var_Name> -> <Field_Name> Vídụ: T là con trỏstructgồm 2 thànhphần a và b thì T->a và T->b làgiátrịcácthànhphầna,btạiđịachỉmà T trỏvào. Ghichú: phéptoánnàychúng ta sẽnóithêmtrongchươngcấutrúc

  10. Chú ý • Cầnchú ý rằngviệcthayđổigiátrịcủa pi sẽlàmchogiátrịcủa a thayđổitheovàngượclại. • Khi ta khaibáo: inta=10; int *pi=&a; // pi giữ địa chỉ biến a *pi=*pi +2; • sẽ làm cho biến a có giá trị là 12 • Lưu ý: Việc sử dụng và thao tác trên giá trị tại địa chỉ của con trỏ chỉ được thực hiện sau khi con trỏ đã có địa chỉ

  11. Các thao tác trên con trỏ • Lệnhgán con trỏ Cóthểdùngphépgánđểgángiátrịcủamột con trỏchomột con trỏkháccócùngkiểu Khi ta khaibáo: int x; int *p1, *p2; p1 = &x; // p1 giữ địa chỉ biến a p2 = p1; cả hai p1 và p2 cùngtrỏđếnbiến x.

  12. 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à trừ • Khi cộng (+) hoặc trừ (-) 1 con trỏ với 1 số nguyên N; kết quả trả về là 1 con trỏ. Con trỏ này trỏ đến vùng nhớ cách vùng nhớ của con trỏ hiện tại một số nguyên lần kích thước của kiểu dữ liệu của nó.

  13. Ví dụ: char *a;short *b;long *c;  Khi đó: a = a + 1; // trỏ vào 1 byte tiếp theob = b + 1; // trỏ vào 2 bytes tiếp theoc = c + 1; // trỏ vào 4 bytes tiếp theo

  14. Minh họa

  15. Ví dụ #include <iostream.h> #include<conio.h> voidmain () { int a = 20, b = 15, *pa, *pb, temp; pa = &a; // con trỏ pa chứa địa chỉ của a pb = &b; // con trỏ pb chứa địa chỉ của b temp = *pa; *pa = *pb; *pb = temp; cout << "a = " << a << endl; cout << “b = ” << b; } // kết quả xuất ra màn hình ? a = 15 b = 20

  16. 3. Cấp phát bộ nhớ động • Ý nghĩa của việc cấp phát động bộ nhớ • Biến toàn cục (global variables) được cấp phát bộ nhớ vào lúc biên dịch. Biến cục bộ (local variables) dùng stack. Tuy nhiên, biến toàn cục hay cục bộ không thể được tạo thêm trong khi thực thi chương trình. Một số chương trình cần thêm bộ nhớ khi thực thi giải pháp cho vấn đề này là cấp phát động. • Cấp phát động là phương tiện nhờ đó một chương trình có thể dành được thêm bộ nhớ trong khi đang thực thi. • Con trỏ cung cấp sự hổ trợ cho cấp phát bộ nhớ động trong C/C++.

  17. 3.1. Cấp phát bộ nhớ động bởi C++ C++ cung cấp hai toán tử cấp phát bộ nhớ động: new vàdelete. • Toán tử newcấp phát bộ nhớ và trả về một con trỏ đến byte đầu tiên của vùng nhớ được cấp phát. • 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: <pointer_var_name>=new <Type>; Hoặc <pointer_var_name>=new <Type>[N_blocks]; delete <pointer_var_name>; delete p;

  18. Lưu ý: • Cần kiểm tra xem việc cấp phát bộ nhớ có thành công hay không. Nếu thành công, con trỏ trỏ đến địa chỉ đầu khối nhớ được cấp phát và lúc này chúng ta mới có thể thực hiện các thao tác trên con trỏ này. • Khi ta khai báo: int *pi; pi= new int; if (pi==NULL) { cout<<"khong du bo nho"; exit(0); /* kết thúc CTr, trả về mã lỗi Code (0) cho hệ thống*/ }

  19. Ví dụ: #include <iostream.h> intmain() { int *p; p = new int; if (p==NULL) { cout<<"khong du bo nho"; exit(0); } *p = 100; cout << "At " << p << " "; cout << "is the value " << *p << "\n"; delete p; return 0; }

  20. 4. Cấp phát bộ nhớ động bởi C Ngoài ra, C còn cung cấp một hàm cấp phát và giải phóng bộ nhớ động như malloc(), calloc(), free()… Cú pháp: • cấp phát bộ nhớ void * malloc (unsigned N_bytes); • void * calloc(unsigned N_Blocks,unsigned N_bytes); • Hủy bộ nhớ • void free (<pointer_var_name>) // hủy bộ nhớ (xem giáo trình)

  21. Từ khóa sizeof •  Cú pháp: sizeof(<type>) Hoặc sizeof(<expression>) • Tác dụng: Cho biết kích thước của kiểu dữ liệu hoặc của biểu thức • Khi ta khai báo: cout<<sizeof(char); cout<<sizeof(int); cout<<sizeof(float); cout<<sizeof(double); cout<<sizeof(long double); // kết quả xuất ra màn hình ? 1 2 4 8 10

  22. 6. 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 *PointerName; • Ví dụ: void *p; p = &a; // p trỏ đến biến nguyên a p = &f; //p trỏ đến biến thực f

  23. Tương thích và không tương thích kiểu • Kiểu dữ liệu khi khai báo biến con trỏ chính là kiểu dữ liệu của ô nhớ mà con trỏ có thể trỏ đến. • Địa chỉ đặt vào biến con trỏ phải cùng kiểu với kiểu của con trỏ. Tuy nhiên, ta cũng có thể ép kiểu con trỏ về đúng kiểu tương ứng khi dùng trong các biểu thức. • Ví dụ: int a; float f; int *pa; float *pf; pa = &a; pf = &f; // hợp lệ pa = &f; pf = &a; //không hợp lệ

  24. 7. Con trỏ null • Khi một con trỏ chưa trỏ tới bất kỳ một địa chỉ nào cả thì con trỏ đó là con trỏ NULL #include <iostream.h> void main() { int *p; // p la con trỏ NULL cout <<“Gia tri con tro p tro den la: “<< *p; } NULL POINTER ASSIGNMENT

  25. 8. Con trỏ và mảng Giữa mảng và con trỏ có một sự liên hệ rất chặt chẽ: • Những phần tử của mảng được xác định bằng chỉ số trong mảng và cũng có thể được xác định qua biến con trỏ. • Tên của một mảng tương đương với địa chỉ phần tử đầu tiên của nó, tương tự một con trỏ tương đương với địa chỉ của phần tử đầu tiên mà nó trỏ tới.

  26. Ví dụ 1: char ch[10], *p; p = ch; • p được gán địa chỉ của phần tử đầu tiên của mảng ch. p = ch; • Để tham chiếu phần tử thứ 3 trong mảng ch, ta dùng một trong 2 cách sau: ch[2] hoặc *(p+2).

  27. Ví dụ: int Numbers[5]; Numbers 10 20 30 50 40 int *p; p p p= Numbers; 20 *p = 10; *p = 20; p++; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; p p p p p

  28. 9. 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ỏ.

  29. Ví dụ: int *p[5]; P[0] P[1] P[2] P[3] P[4] int a=6; 100 100 p p[0] = &a; a 100 p[2] = p[0]; 6 6 int b; b = *p[0]; b

  30. Tìm số lớn nhất của một dãy số nguyên n phần tử nhập từ bàn phím? intmain() { int*px; int n; cin>>n; px=new int[n]; for (int i=0; i<n; i++) cin>>*(px+i); int max=*px; for (int i=1;i<n;i++) if (*(px+i)>max) max=*(px+i); cout<<max; return 0; }

  31. Thực hiện bài tập chương 5

More Related