Chương 7: Kiểu con trỏ
1
Chương 7
KIỂU CON TRỎ
Chương 7: Kiểu con trỏ
2
Nội dung
• Khái niệm
• Khai báo và sử dụng
Chương 7: Kiểu con trỏ
3
Khái niệm
• Con trỏ là 1 phần quan trọng trong ngôn ngữ C.
• Con trỏ là 1 kiểu dữ liệu đặc biệt, được sử dụng để lưu
địa chỉ trong bộ nhớ.
• Kích thước của biến con trỏ không phụ thuộc vào kiểu
dữ liệu, luôn có kích thước cố định là 2 byte.
• Việc truyền tham biến cho chương trình con cần thông
qua biến con trỏ.
• Việc thao tác với dữ liệu sẽ mềm dẻo hơn với con trỏ,
chương trình chạy nhanh hơn,
Chương 7: Kiểu con trỏ
4
Khai báo con trỏ
• Cú pháp: <Kiểu dữ liệu> *<Tên con trỏ>;
• Ý nghĩa:
– Ki
ể
u d
ữ
li
ệ
u: là ki
ể
u d
ữ
li
ệ
u c
ủ
a bi
ế
n (ô nh
ớ
) mà con tr
ỏ
có ý
đị
nh l
ư
u tr
ữ đị
a ch
ỉ
.
– D
ấ
u * là ký hi
ệ
u s
ử
d
ụ
ng khi khai báo ki
ể
u con tr
ỏ
.
• Ví dụ:
int *p; // con tr
ỏ
p s
ẽ đượ
c l
ư
u tr
ữ đị
a ch
ỉ
c
ủ
a bi
ế
n nguyên
int i;
p=&i; // gán
đị
a ch
ỉ
c
ủ
a bi
ế
n i cho con tr
ỏ
p
• Khi chưa muốn khai báo kiểu dữ liệu ta có thể khai báo
void *ptr;
Chương 7: Kiểu con trỏ
5
Các thao tác trên con trỏ
• Gán địa chỉ của biến cho biến con trỏ
<Tên biến con trỏ> = &<Tên biến>;
Vd: pa=&a;
• nội dung của ô nhớ con trỏ chỉ tới
*<Tên biến con trỏ>;
Vd: a=5; pa=&a; b=*p;
int *p, i=2;
p=&i;
printf("%d", *p); // in giá trị i
scanf("%d", p); // nhập số nguyên vào i
Chương 7: Kiểu con trỏ
6
Cấp phát vùng nhớ cho biến con trỏ
• void *malloc(<size>);
Cấp phát vùng nhớ có kích thước là size.
• void *calloc(<nitems>, <size>);
Cấp phát vùng nhớ có kích thước là nitems*size.
int a, *pa, *pb;
pa = (int *) malloc(sizeof(int));
/* C
ấ
p phát vùng nh
ớ
có kích th
ướ
c b
ằ
ng
v
ớ
i kích th
ướ
c c
ủ
a m
ộ
t s
ố
nguyên */
pb= (int *)calloc(10, sizeof(int));
/* C
ấ
p phát vùng nh
ớ
có th
ể
ch
ứ
a
đượ
c 10 s
ố
nguyên*/
Chương 7: Kiểu con trỏ
7
Cấp phát vùng nhớ cho biến con trỏ
• void *realloc(*<block>, <size>);
Cấp phát lại một vùng nhớ cho con trỏ block quản lý,
vùng nhớ này có kích thước mới là size;
• Giải phóng vùng nhớ: void free(*<block>);
Giải phóng vùng nhớ được quản lý bởi con trỏ block.
Thư viện hỗ trợ: <malloc.h>, <alloc.h>
Chương 7: Kiểu con trỏ
8
Phép toán
• Phép gán:
int a, *p, *q ; float *f;
a = 5; p = &a ; q = p; //đúng
f = p; // sai do khác kiểu
f = (float*)p; // Đúng nhờ ép kiểu
Ép kiểu: (<Kiểu kết quả>*)<Tên con trỏ>
Chương 7: Kiểu con trỏ
9
Phép toán
• Cộng, trừ con trỏ với 1 số nguyên: giả sử p
là con trỏ, k là 1 số nguyên
– Phép cộng: p=p+k;
• p trỏ sang ô nhớ sau ô nhớ trước đó k ô nhớ
– Phép trừ: p= p-k;
• P trỏ sang ô nhớ trước ô nhớ trước đó k ô nhớ
• Con trỏ NULL:
– là con trỏ không chứa địa chỉ nào cả
– có thể gán con trỏ NULL cho 1 con trỏ có kiểu bất kỳ
Chương 7: Kiểu con trỏ
10
Truyền tham biến cho hàm
• Truyền tham biến cho hàm:
– Mặc nhiên, trong C chỉ cho phép truyền tham trị. Các
giá trị được truyền không bị thay đổi.
– Để truyền tham biến cho hàm, thay gì truyền các
biến ta hãy truyền địa chỉ của chúng.
• Hàm sẽ làm việc trên bản copy của địa chỉ
truyền vào
• Bản copy và bản gốc cùng trỏ vào 1 biến, do vậy
nếu thay đổi nội dung của địa chỉ đó thì kết quả sẽ
được giữa lại.
Chương 7: Kiểu con trỏ
11
Ví dụ
//Hàm tính t
ổ
ng và hi
ệ
u 2 s
ố
nguyên
#include <stdio.h>
void tong_hieu(int a, int b, int *tong, int *hieu);
int main(){
int x=3,y=4,t,h;
tong_hieu(x,y,&t,&h);
printf(“tong=%d;hieu=%d”,t,h); return 0;
}
void tong_hieu(int a, int b, int *tong, int *hieu){
*tong = a+b;
*hieu = a-b;
}
Chương 7: Kiểu con trỏ
12
Con trỏ với mảng 1 chiều
• C xem biến mảng 1 chiều như 1 hằng con trỏ có:
– Kiểu ô nhớ trỏ đến là kiểu phần tử của mảng.
– Giá trị là địa chỉ phần tử đầu tiên (chỉ số 0) của mảng
– Ví dụ:
int m[10];
int *p;
printf(“%d”,*m); // vi
ế
t ra ph
ầ
n t
ử đầ
u tiên c
ủ
a m
ả
ng m
p=m; // sau câu l
ệ
nh này có th
ể
coi p là m
ả
ng m
printf(“%d”,*(m+3)); // vi
ế
t ra ph
ầ
n t
ử
th
ứ
4 c
ủ
a m
ả
ng m
Chương 7: Kiểu con trỏ
13
Con trỏ với mảng 1 chiều
• <Tên biến>[<Vị trí>]
tương đương với *(<Tên biến> + <Vị trí>).
• &<Tên biến>[<Vị trí>]
tương đương với (<Tên biến> + <Vị trí>).
• <Tên mảng>[<Vị trí>]
tương đương với *(<Tên mảng> + <Vị trí>).
Chương 7: Kiểu con trỏ
14
ví dụ
#include <stdio.h>
#include <alloc.h>
#include <conio.h>
int main()
{ int *a;
a=(int*)malloc(sizeof(int)*10);
for(int i=0;i<10;i++) a[i] = 2*i;
printf("Truy cap theo kieu mang: ");
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("\nTruy cap theo kieu con tro: ");
for(i=0;i<10;i++)
printf("%d ",*(a+i));
getch();
return 0;
}
Chương 7: Kiểu con trỏ
15
Con trỏ & tham số hình thức của hàm
void HoanVi(int *a, int *b)
{
int c=*a;
*a=*b;
*b=c;
}
Chương 7: Kiểu con trỏ
16
Bài tập
• Viết chương trình nhập vào một dãy n số nguyên và
thực hiện các yêu cầu sau (dùng kiểu con trỏ):
– Cho bi
ế
t có bao nhiêu s
ố
ch
ẵ
n trong dãy, tính t
ổ
ng các ph
ầ
n
t
ử
ch
ẵ
n trong dãy.
– Tìm ph
ầ
n t
ử
ch
ẵ
n nh
ỏ
nh
ấ
t (n
ế
u có).
– Vi
ế
t hàm tìm v
ị
trí ph
ầ
n t
ử
x
đầ
u tiên trong (n
ế
u có). N
ế
u x
không có trong dãy thì tr
ả
v
ề
-1.
In t
ấ
t c
ả
các k
ế
t qu
ả
th
ự
c hi
ệ
n ra màn hình.
• Viết chương trình nhập vào 2 dãy số nguyên a, b:
– In ra các ph
ầ
n t
ử
ch
ỉ
xu
ấ
t hi
ệ
n trong dãy a mà không xu
ấ
t
hi
ệ
n trong b.
– In ra nh
ữ
ng ph
ầ
n t
ử
xu
ấ
t hi
ệ
n
ở
c
ả
2 dãy.