Trường Đại Học Công Nghiệp TP. HCM Khoa Công Nghệ Thông Tin

CHƯƠNG 3: KIỂU CON TRỎ(p2)

Võ Quang Hoàng Khang

Email: vqhkhang@gmail.com

1

&

VC

Nội dung

1

BB

Cấp phát bộ nhớ động

2

Con trỏ và mảng một chiều

3

Con trỏ và cấu trúc

4

Bài tập – Kiểm tra

22

&

VC

Cấp phát bộ nhớ tĩnh và động

BB

Cấp phát tĩnh (static memory allocation)  Khai báo biến, cấu trúc, mảng, …  Bắt buộc phải biết trước cần bao nhiều bộ nhớ lưu trữ  tốn bộ nhớ, không thay đổi được kích thước, …

Cấp phát động (dynamic memory allocation)

 Cần bao nhiêu cấp phát bấy nhiêu.  Có thể giải phóng nếu không cần sử dụng.

33

&

VC

Cấp phát bộ nhớ động

BB

Thuộc thư viện hoặc

 malloc  calloc  free

Trong C++  new  delete

44

&

VC

Cấp phát bộ nhớ động

BB

void *malloc(size_t size)

Cấp phát một vùng nhớ size (bytes)

Con trỏ đến vùng nhớ được cấp phát NULL nếu không đủ bộ nhớ

int *p = (int *)malloc(10*sizeof(int)); if (p == NULL)

printf(“Không đủ bộ nhớ! ”);

55

&

VC

Cấp phát bộ nhớ động

BB

void *calloc(size_t num, size_t size)

Cấp phát vùng nhớ gồm num phần tử, mỗi phần tử kích thước size (bytes)

Con trỏ đến vùng nhớ được cấp phát NULL nếu không đủ bộ nhớ

int *p = (int *)calloc(10, sizeof(int)); if (p == NULL)

printf(“Không đủ bộ nhớ! ”);

66

&

VC

Cấp phát bộ nhớ động

BB

void *free(void *ptr)

Giải phóng vùng nhớ do ptr trỏ đến, được cấp bởi các hàm malloc(), calloc(). Nếu ptr là NULL thì không làm gì cả.

Không có

int *p = (int *)malloc(10*sizeof(int)); free(p);

77

&

VC

Cấp phát bộ nhớ động

BB

= new [size]

Cấp phát vùng nhớ có kích thước sizeof()*size

Con trỏ đến vùng nhớ được cấp phát NULL nếu không đủ bộ nhớ

int *a1 = (int *)malloc(sizeof(int)); int *a2 = new int; int *p1 = (int *)malloc(10*sizeof(int)); int *p2 = new int[10];

88

&

VC

Cấp phát bộ nhớ động

BB

delete []

Giải phóng vùng nhớ do trỏ đến (được cấp phát bằng new)

Không có!

int *a = new int; delete a; int *p = new int[10]; delete []p;

99

&

VC

Cấp phát bộ nhớ động

BB

Lưu ý

 Cấp phát bằng malloc, calloc thì giải phóng bằng free, cấp phát bằng new thì giải phóng bằng delete.

 Cấp phát bằng new thì giải phóng bằng

delete, cấp phát mảng bằng new [] thì giải phóng bằng delete [].

1010

&

VC

Con trỏ và mảng một chiều

BB

Mảng một chiều

int array[3];

 Tên mảng array là một hằng con trỏ

 không thể thay đổi giá trị của hằng này.

 array là địa chỉ đầu tiên của mảng

array == &array[0]

0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17

1111

array

&

VC

Con trỏ và mảng một chiều

BB

Con trỏ đến mảng một chiều

int array[3], *parray;

parray = array; parray = &array[0];

// Cách 1 // Cách 2

18 19 1A 1B 1C 1D 1E 1F

0B 00 00 00

parray

0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17

1212

array

&

VC

Phép toán số học trên con trỏ

BB

Phép cộng (tăng)

 + n  + n * sizeof()  Có thể sử dụng toán tử gộp += hoặc ++

p = array

+2

+1

0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17

1313

int array[3];

&

VC

Phép toán số học trên con trỏ

BB

Phép trừ (giảm)

 – n  – n * sizeof()  Có thể sử dụng toán tử gộp –= hoặc – –

p = &array[2]

–2

–1

0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17

1414

int array[3];

&

VC

Phép toán số học trên con trỏ

BB

Các phép toán khác

 Phép so sánh: So sánh địa chỉ giữa hai con

trỏ (thứ tự ô nhớ) • == != >= • > <= • <

 Không thể thực hiện các phép toán: * / %

1515

&

VC

Con trỏ và mảng một chiều

BB

Truy xuất đến phần tử thứ n của mảng (không

sử dụng biến mảng)  array[n] == p[n] == *(p + n)

(*

p

+ 2 )

0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17

1616

int array[3];

&

VC

Con trỏ và mảng một chiều

BB

Ví dụ nhập mảng

void main() {

int a[10], n = 10, *pa; pa = a;

// hoặc pa = &a[0];

for (int i = 0; i

}  &a[i]  (a + i)  (p + i)  &p[i]

1717

&

VC

Con trỏ và mảng một chiều

BB

Ví dụ xuất mảng

void main() {

// hoặc pa = &a[0];

int a[10], n = 10, *pa; pa = a; … for (int i = 0; i

}  a[i]  *(a + i)  *(p + i)  p[i]

1818

&

VC

Con trỏ và mảng một chiều

BB

Lưu ý

 Không thực hiện các phép toán nhân, chia,

lấy phần dư.

 Tăng/giảm con trỏ n đơn vị có nghĩa là

tăng/giảm giá trị của nó n*sizeof()

 Không thể tăng/giảm biến mảng. Hãy gán một

con trỏ đến địa chỉ đầu của mảng và tăng/giảm nó.

1919

&

VC

Con trỏ cấu trúc

BB

Truy xuất bằng 2 cách

-> (*).

Ví dụ

struct PHANSO {

int tu, mau;

// ps2 là con

}; PHANSO ps1, *ps2 = &ps1; trỏ

2020

ps1.tu = 1; ps1.mau = 2; ps2->tu = 1; ps2->mau = 2; (*ps2).tu = 1; (*ps2).mau = 2;

&

VC

Con trỏ cấu trúc

BB

Gán hai cấu trúc

struct PHANSO {

int tu, mau;

}; PHANSO ps1, *ps2;

ps1.tu = 1; ps1.mau = 2;

// ps1 = 1/2

ps2 = &ps1; ps2->tu = 3; ps2->mau = 4;

// ps1 = 3/4

2121

&

VC

Bài tập

BB

Sử dụng con trỏ để làm lại các bài tập về mảng một chiều.

2222

&

VC

Bài tập mẫu – Nhập mảng

BB

void NhapM(int *a,int n) {

for(int i=0;i>*(a+i);

}

2323

&

VC

Bài tập mẫu – Xuất mảng

BB

void XuatM(int *a,int n) {

for(int i=0;i

cout<<*(a+i)<<"\t";

cout<<"\n";

}

2424

&

VC

Bài tập mẫu – main

BB

int main() {

int *a,n; cout<<"Nhap so phan tu:"; cin>>n; a=new int[n]; NhapM(a,n); cout<<"\nMang da nhap:\n"; XuatM(a,n); return 0;

2525

}