• 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.. Cấ
Trang 1Chương 7 KIỂU CON TRỎ
Trang 2Nội dung
• Khái niệm
• Khai báo và sử dụng
Trang 3Khá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,
Trang 4Khai 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;
Trang 5Cá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
Trang 6Cấ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*/
Trang 7Cấ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>
Trang 8Phép toán
• Phép gán:
int a, *p, *q ; float *f;
Ép kiểu: (<Kiểu kết quả>*)<Tên con trỏ>
Trang 9Phép toán
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ỳ
Trang 10Truyề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
Trang 11Ví dụ
#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;
}
Trang 12Con 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
Trang 13Con 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ươ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í>).
Trang 14ví 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;
Trang 15Con trỏ & tham số hình thức của hàm
void HoanVi(int *a, int *b)
{
int c=*a;
*a=*b;
*b=c;
}
Trang 16Bà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.