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.
25 trang |
Chia sẻ: thuychi16 | Lượt xem: 849 | Lượt tải: 1
Bạn đang xem trước 20 trang tài liệu Kĩ thuật lập trình - Chương 3: Kiểu con trỏ (phần 2), để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
1Trườ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
VC
&
BB
2
Nội dung
Cấp phát bộ nhớ động1
Con trỏ và mảng một chiều2
Con trỏ và cấu trúc3
Bài tập – Kiểm tra4
VC
&
BB
3
Cấp phát bộ nhớ tĩnh và động
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.
VC
&
BB
4
Cấp phát bộ nhớ động
Thuộc thư viện hoặc
malloc
calloc
free
Trong C++
new
delete
VC
&
BB
5
Cấp phát bộ nhớ động
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ớ! ”);
void *malloc(size_t size)
VC
&
BB
6
Cấp phát bộ nhớ động
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ớ! ”);
void *calloc(size_t num, size_t size)
VC
&
BB
7
Cấp phát bộ nhớ động
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);
void *free(void *ptr)
VC
&
BB
8
Cấp phát bộ nhớ động
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];
= new [size]
VC
&
BB
9
Cấp phát bộ nhớ động
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;
delete []
VC
&
BB
10
Cấp phát bộ nhớ động
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 [].
VC
&
BB
11
Con trỏ và mảng một chiều
Mảng một chiều
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]
int array[3];
array
0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17
VC
&
BB
12
Con trỏ đến mảng một chiều
Con trỏ và mảng một chiều
int array[3], *parray;
parray = array; // Cách 1
parray = &array[0]; // Cách 2
array
0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17
18 19 1A 1B 1C 1D 1E 1F
parray
0B 00 00 00
VC
&
BB
13
Phép cộng (tăng)
+ n + n * sizeof()
Có thể sử dụng toán tử gộp += hoặc ++
+2
Phép toán số học trên con trỏ
p = array
0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17
+1
int array[3];
VC
&
BB
14
Phép trừ (giảm)
– n – n * sizeof()
Có thể sử dụng toán tử gộp –= hoặc – –
Phép toán số học trên con trỏ
p = &array[2]
–1
–2
0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17
int array[3];
VC
&
BB
15
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: * / %
Phép toán số học trên con trỏ
VC
&
BB
16
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)
Con trỏ và mảng một chiều
p
0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17
int array[3];
+ 2 )(*
VC
&
BB
17
Con trỏ và mảng một chiều
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<n; i++)
scanf(“%d”, &a[i]);
scanf(“%d”, &p[i]);
scanf(“%d”, a + i);
scanf(“%d”, p + i);
scanf(“%d”, a++);
scanf(“%d”, p++);
}
&a[i] (a + i) (p + i) &p[i]
VC
&
BB
18
Con trỏ và mảng một chiều
Ví dụ xuất mảng
void main()
{
int a[10], n = 10, *pa;
pa = a; // hoặc pa = &a[0];
for (int i = 0; i<n; i++)
printf(“%d”, a[i]);
printf(“%d”, p[i]);
printf(“%d”, *(a + i));
printf(“%d”, *(p + i));
printf(“%d”, *(a++));
printf(“%d”, *(p++));
}
a[i] *(a + i) *(p + i) p[i]
VC
&
BB
19
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(<kiểu dữ liệu
mà nó trỏ đến>)
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ó.
Con trỏ và mảng một chiều
VC
&
BB
20
Con trỏ cấu trúc
Truy xuất bằng 2 cách
Ví dụ
struct PHANSO
{
int tu, mau;
};
PHANSO ps1, *ps2 = &ps1; // ps2 là con
trỏ
ps1.tu = 1; ps1.mau = 2;
ps2->tu = 1; ps2->mau = 2;
(*ps2).tu = 1; (*ps2).mau = 2;
->
(*).
VC
&
BB
21
Con trỏ cấu trúc
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
VC
&
BB
22
Bài tập
Sử dụng con trỏ để làm lại các bài tập về mảng
một chiều.
VC
&
BB
23
Bài tập mẫu – Nhập mảng
void NhapM(int *a,int n)
{
for(int i=0;i<n;i++)
cin>>*(a+i);
}
VC
&
BB
24
Bài tập mẫu – Xuất mảng
void XuatM(int *a,int n)
{
for(int i=0;i<n;i++)
cout<<*(a+i)<<"\t";
cout<<"\n";
}
VC
&
BB
25
Bài tập mẫu – main
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;
}