22
1 Con tr1. Biến và con tr2. Cp phát và gii phóng bnhớ động 3. Mô hình bnhchương trình 4. Quan hgiamng và con tr5. Phân bit tham chiếu và con tr6. Mng con tr. Con trcu trúc. Con trvoid 7. Con trlàm đốistrong hàm 8. Review 9. Bài tp

Bai Giang 8

  • Upload
    nbb3i

  • View
    3.975

  • Download
    2

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Bai Giang 8

1

Con trỏ

1. Biến và con trỏ2. Cấp phát và giải phóng bộ nhớ động3. Mô hình bộ nhớ chương trình4. Quan hệ giữa mảng và con trỏ5. Phân biệt tham chiếu và con trỏ6. Mảng con trỏ. Con trỏ cấu trúc. Con trỏ void7. Con trỏ làm đối số trong hàm8. Review9. Bài tập

Page 2: Bai Giang 8

2

Biến và con trỏ

Khai báoint a = 5; // a là biến chứa giá trị intint *p; // p là con trỏ int, p là biến chứa địa chỉ

// của ô nhớ kiểu intTruy nhập ô nhớ

p = &a; // toán tử & cho phép lấy địa chỉ của một biến, // p chứa địa chỉ của biến a

*p = 7; // toán tử * cho phép truy nhập giá trị ô nhớ// thông qua địa chỉ, giá trị của ô nhớ có địa// chỉ trong p được gán giá trị 7

Page 3: Bai Giang 8

3

Biến và con trỏ

Mô tả:1. int a = 5; // a là biến chứa giá trị int2. int *p; // p là con trỏ int, p là biến chứa địa chỉ3. p = &a; // p trỏ đến a4. *p = 7; // gán giá trị qua p

51001

a

1100

p

1. Cấp ô nhớ cho a

10011100

p2. Cấp ô nhớ cho p

51001

a

3. p chứa địa chỉcủa biến a

10011100

p

71001

a

4. gán giá trị vào ô nhớ có địa chỉ trong p

Page 4: Bai Giang 8

4

Biến và con trỏ

Cho biết kết quả trên màn hình:int a = 5;int *p;p = &a;cout<< *p <<“\t”<< a <<endl;*p = 8;cout<< *p <<“\t”<< a <<endl;a = 9;cout<< *p <<“\t”<< a <<endl;

Page 5: Bai Giang 8

5

Cấp phát và giải phóng bộ nhớ động

Biến tĩnhLà biến được cấp vùng nhớ ngay khi lời khai báođược thực hiệnTự động mất đi khi ra khỏi phạm vi khai báoBiến tĩnh thường được sử dụng thông qua tên biến

Biến độngLà biến được cấp vùng nhớ bất kì khi nào chươngtrình yêu cầuBị mất đi khi chương trình giải phóng vùng nhớBiến động thường được sử dụng thông qua con trỏ

Page 6: Bai Giang 8

6

Cấp phát và giải phóng bộ nhớ động

Toán tử new: Cấp phát vùng nhớint *p, *q, *r;p = new int; // cấp phát ô nhớ cỡ intq = new int(5); // cấp phát đồng thời khởi tạo giá trịr = new int[8]; // cấp phát mảng động

Toán tử delete: Giải phóng vùng nhớdelete p; // giải phóng vùng nhớ do p trỏ đếndelete[] r; // giải phóng mảng động

Page 7: Bai Giang 8

7

Cấp phát và giải phóng bộ nhớ động

Ví dụ:// biến độngint *p = new int(5); // cấp phát ô nhớcout<< *p << endl;delete p; // giải phóng ô nhớ

// mảng độngint *r = new int[7]; // cấp phát mảng độngfor(int i = 0; i<7; i++){

r[i] = 3;cout<<r[i]<<endl;

}delete[ ] r; // giải phóng mảng động

Page 8: Bai Giang 8

8

Cấp phát và giải phóng bộ nhớ động

Chú ý: Khi giải phóng một vùng nhớ thì con trỏtrỏ đến vùng nhớ đó vẫn chứa địa chỉ của vùngnhớ, và như vậy việc truy nhập đến vùng nhớ đãgiải phóng là không hợp lệ (về logic).=> Khi giải phóng vùng nhớ, nên gán tất cả con trỏ trỏđến vùng nhớ đó bằng NULL.

delete p; // giải phóng vùng nhớ do p trỏ đếnp = NULL; // p không chứa địa chỉ của vùng nhớ nào,

// p không trỏ đến vùng nhớ nàoKhông giải phóng một vùng nhớ đã cấp phát sẽdẫn đến hiện tượng rò bộ nhớ (memory leak).

Page 9: Bai Giang 8

9

Cấp phát và giải phóng bộ nhớ động

Cho biết kết quả của đoạn chương trình sau:int *p, *q;p = new int(1);q = new int(2);cout<< *p <<"\t"<< *q <<endl;*p = *q + 3;cout<< *p <<"\t"<< *q <<endl;p = q;cout<< *p <<"\t"<< *q <<endl;*p = 7;cout<< *p <<"\t"<< *q <<endl;p = new int;delete p;p = NULL;q = NULL;

Page 10: Bai Giang 8

10

Mô hình bộ nhớ chương trình

Khi một chương trình được thực thi (execute), nó có các vùng nhớ như sau:

Vùng CODE: Chứa mã lệnh chương trìnhVùng DATA: Chứa các biến toàn cụcVùng STACK: Chứa các biến cục bộVùng HEAP: Chứa các biến động

Kích thước của vùng có thể được thiết đặt trướckhi biên dịch.

Page 11: Bai Giang 8

11

Mô hình bộ nhớ chương trình

Thử nghiệm:#include <iostream.h>int g;void test(int x){ int c;

cout<<“Dia chi cua x la: “<< &x <<endl;cout<<“Dia chi cua c la: “<< &c <<endl;

}void main(){ int m;

cout<<“Dia chi cua m la: ”<< &m <<endl;test(8);cout<<“Dia chi cua g la: ”<< &g <<endl;int *p = new int;cout<<“Dia chi p la: ”<< p <<endl;

}

Page 12: Bai Giang 8

12

Mảng và con trỏ

Trong C++, mảng là con trỏ hằng trỏ đến mộtdãy ô nhớ.Ví dụ: int x[7]; int a; int *p;

x là một mảng, x là con trỏ hằng trỏ đến ô nhớ đầutiên của 7 ô nhớ được cấp phátVì x là con trỏ hằng nên ta không thể thay đổi giá trịđịa chỉ mà nó lưu giữ, ví dụ: x = &a; Vì p cũng là con trỏ nên ta có thể gán p = x;x trỏ đến ô nhớ đầu tiên, x+1 trỏ đến ô nhớ tiếptheo... Vậy ta có *(x+1) tương đương với x[1]...

Page 13: Bai Giang 8

13

Mảng và con trỏ

Cho biết kết quả của đoạn chương trình sau:int x[5] = {5, 3, 4, 8, 9};int *p = x;*p = 1;*(p+1) = 7;p[2] = 15;x[3] = p[3] + 2;for(int i=0; i<5; i++)

cout<<x[i]<<endl;

Page 14: Bai Giang 8

14

Con trỏ và tham chiếu

Con trỏ và tham chiếu hoạt động gần giốngnhau song chúng khác nhau.Tham chiếu: Là bí danh của một biến.Con trỏ: Là biến chứa địa chỉ.Có thể tạo tham chiếu tới một biến động. Ví dụ:

int *p = new int(3); // tạo biến độngint &x = *p; // tạo tham chiếu tới biến độngcout<<x<<endl;cout<<&x<<endl<<p;

Page 15: Bai Giang 8

15

Mảng con trỏ

Cho biết kết quả của đoạn chương trình sau:int *r[5]; // khai báo mảng 5 con trỏint i;for(i=0; i<5; i++){

r[i] = new int(i*2); // cấp phát vùng nhớ cho từng con trỏcout<<*(r[i])<<endl;

}for(i=0; i<5; i++){

delete r[i]; // giải phóng vùng nhớr[i] = NULL;

}

Page 16: Bai Giang 8

16

Con trỏ cấu trúc

Ví dụ cấu trúc Hàng hoástruct Hanghoa{

int soluong;float dongia;

};...Hanghoa x;Hanghoa *p, *q;p = &x;q = new Hanghoa;q->soluong = 7; // giống (*q).soluong = 7;q->dongia = 20.50; // giống (*q).dongia = 20.50;

Page 17: Bai Giang 8

17

Con trỏ void

Con trỏ void là con trỏ có thể trỏ đến bất kỳ đốitượng nào. Khi muốn lấy giá trị của nó ta cầnphải ép kiểu.

void* p;p = new int(4); // p trỏ đến một vùng nhớ kiểu intcout<< *((int *) p); // ép kiểu để lấy giá trị int

p = new Hanghoa; // p trỏ đến một vùng nhớ kiểu Hanghoacout<< ((Hanghoa *) p)->soluong; // ép kiểu Hanghoa

p = new Sinhvien; // p trỏ đến một vùng nhớ kiểu Sinhvien((Sinhvien *) p)->DatDTB(8.7); // ép kiểu Sinhvien

p = new Hinhtron(4); // p trỏ đến một vùng nhớ kiểu Hinhtroncout<< ((Hinhtron *) p)->LayDientich(); // ép kiểu Hinhtron

Page 18: Bai Giang 8

18

Con trỏ và hàm

Con trỏ làm đối số: Thường được dùng khi đốisố truyền vào là một mảng

void display(int *p, int n){

for(int i=0; i<n; i++)cout<<p[i]<<endl;

}void main(){

int x[5] = {3, 8, 2, 9, 4};display(x, 5);

}

Page 19: Bai Giang 8

19

Con trỏ và hàm

Con trỏ làm kết quả trả về: Thường được dùngđể trả về một xâu kí tự hay một mảng.

class Sinhvien{private:

char ten[30];public:

char* LayTen();};char* Sinhvien::LayTen(){

return ten;}

Page 20: Bai Giang 8

20

Con trỏ và hàm

Tham chiếu con trỏ: Được dùng khi muốn thayđổi giá trị địa chỉ trong con trỏ.

void test(int *&p){

...}

Con trỏ hàm: (Bài 6)typedef void (*FunctionType)(int x);

Page 21: Bai Giang 8

21

Review

1. Biến và con trỏ khác nhau thế nào ?2. Phân biệt biến tĩnh và biến động ?3. Nêu các vùng nhớ của chương trình ?4. Trong C++, mảng là con trỏ như thế nào ?5. Tham chiếu khác con trỏ như thế nào ?6. Con trỏ void là gì ?7. Nêu một số ví dụ về sử dụng con trỏ hàm ?

Page 22: Bai Giang 8

22

Bài tập về nhà

1. Sử dụng lớp Hinhtron để viết chương trình tạohình tròn (cấp phát động) với các lời gọi cấu tửkhác nhau.

2. Hoàn chỉnh lớp Sinhvien đã học với cácphương thức cần thiết.

3. Viết chương trình nhập một số N, sau đó tạomảng động N phần tử với giá trị là các sốFibonacci. In mảng ra màn hình và cuối cùnggiải phóng mảng.