Upload
kysibongdem
View
220
Download
0
Embed Size (px)
Citation preview
Tin Học Cơ Sở 4
Con trỏ
2
Nôi Dung
• Khai báo
• Các toán tử &, *, =, +• Nhắc lại về truyền tham số địa chỉ
• Con trỏ & mảng
• Cấp phát vùng nhớ động
Lê Nguyên Khôi
Giới thiệu về Con Trỏ
• Định nghĩa Con trỏ:– Kiểu dữ liệu lưu trữ địa chỉ của các vùng dữ liệu trong
bộ nhớ máy tính– Chứa địa chỉ của biến mang giá trị cụ thể
• Mục đích Con trỏ:– Truyền tham số kiểu địa chỉ– Biểu diễn các kiểu & cấu trúc dữ liệu động– Liên quan chặt chẽ đến mảng & xâu
• Con trỏ đã được sử dụng trong hàm scanf
Lê Nguyên Khôi 3
Biến Con Trỏ
• Con trỏ là kiểu dữ liệu– Kiểu con trỏ phải được định nghĩa trên một kiểu cơ
sở đã được định nghĩa trước đó.
typedef kiểucơsở *Tênkiểu;
typedef int * IntPointer;// IntPointer là kiểu con trỏ - địa chỉ vùng nhớ kiểu int
– Có thể dùng biến để lưu trữ con trỏ– Không phải kiểu int, double,…
•Là con trỏ chỉ đến biến kiểu dữ liệu int, double,…
Lê Nguyên Khôi 4
Biến Con Trỏ - Ví dụ
int x;
int *p;
IntPointer p1;– p và p1 được khai báo là con trỏ chỉ đến kiểu int– p và p1 là biến kiểu int*– p và p1 có thể dùng để lưu địa chỉ của biến kiểu int–Có thể sử dụng p và p1 để lưu địa chỉ của x
Lê Nguyên Khôi 5
Khai báo biến Con Trỏ
• Khai báo biến con trỏ giống các biến kiểu dữ liệu khác:– Thêm toán tử * vào trước biến– Tạo ra con trỏ chỉ đến kiểu dữ liệu khai báo
• Toán tử * bắt buộc phải ở trước biến
• int *p1, *p2, v1, v2;– p1, p2 là con trỏ chỉ đến biến kiểu int– v1, v2 là biến kiểu int
Lê Nguyên Khôi 6
Khai báo Con Trỏ trong C
Lê Nguyên Khôi 7
int *pi;
long int *p;
float *pf;
char c, d, *pc; /* c và d kiểu char pc là con trỏ đến char */
double *pd, e, f; /* pd là con trỏ đến double e and f are double */
char *start, *end;
int *pi;
long int *p;
float *pf;
char c, d, *pc; /* c và d kiểu char pc là con trỏ đến char */
double *pd, e, f; /* pd là con trỏ đến double e and f are double */
char *start, *end;
Toán tử &• &: toán tử lấy (trả về) địa chỉ của 1 biến.• Địa chỉ của tất cả các biến trong chương trình đều đã
được chỉ định từ khi khai báo.
Lê Nguyên Khôi 8
0x91A2
0x1132
char g = 'z';
int main(){
char c = 'a';char *p;p = &c;p = &g;return 0;
}
char g = 'z';
int main(){
char c = 'a';char *p;p = &c;p = &g;return 0;
}
p c'a'
0x1132
p g
'z'0x91A2
Toán tử *• *: toán tử truy xuất giá trị của vùng nhớ được quản lý
bởi con trỏ.
Lê Nguyên Khôi 9
'a'
'z'
#include <stdio.h>char g = 'z';int main(){
char c = 'a';char *p;p = &c;printf("%c\n", *p);p = &g;printf("%c\n", *p);return 0;
}
#include <stdio.h>char g = 'z';int main(){
char c = 'a';char *p;p = &c;printf("%c\n", *p);p = &g;printf("%c\n", *p);return 0;
}
az
az
xuất giá trị tại vùng nhớ do p đang quản lý
0x91A2
0x1132
p c
0x1132
p g
0x91A2
Truyền tham số địa chỉ
Lê Nguyên Khôi 10
#include <stdio.h>void ThayDoiTruyenDiaChi(int *v);
int main(){
int var = 5;ThayDoiTruyenDiaChi(&var);printf("main: var = %i\n", var);return 0;
}
void ThayDoiTruyenDiaChi(int *v){
(*v) *= 100;printf(“ham: *v = %i\n", (*v));
}
#include <stdio.h>void ThayDoiTruyenDiaChi(int *v);
int main(){
int var = 5;ThayDoiTruyenDiaChi(&var);printf("main: var = %i\n", var);return 0;
}
void ThayDoiTruyenDiaChi(int *v){
(*v) *= 100;printf(“ham: *v = %i\n", (*v));
}
Truyền tham số giá trị
Lê Nguyên Khôi 11
#include <stdio.h>void ThayDoiTruyenGiaTri(int v);
int main(){
int var = 5;ThayDoiTruyenGiaTri(var);printf("main: var = %i\n", var);return 0;
}
void ThayDoiTruyenGiaTri(int v){
v *= 100;printf(“ham: v = %i\n", v);
}
#include <stdio.h>void ThayDoiTruyenGiaTri(int v);
int main(){
int var = 5;ThayDoiTruyenGiaTri(var);printf("main: var = %i\n", var);return 0;
}
void ThayDoiTruyenGiaTri(int v){
v *= 100;printf(“ham: v = %i\n", v);
}
Con Trỏ NULL
• Giá trị đặc biệt để chỉ rằng con trỏ không quản lý vùng nào. Giá trị này thường được dùng để chỉ một con trỏ không hợp lệ.
Lê Nguyên Khôi 12
#include <stdio.h>int main(){
int i = 13;short *p = NULL;if (p == NULL)
printf(“Con trỏ không hợp lệ!\n");else
printf(“Giá trị : %hi\n", *p);return 0;
}
#include <stdio.h>int main(){
int i = 13;short *p = NULL;if (p == NULL)
printf(“Con trỏ không hợp lệ!\n");else
printf(“Giá trị : %hi\n", *p);return 0;
}
Toán tử gán =
• Có thể gán giá trị cho biến con trỏint *p, *q;p = q;–Gán giá trị con trỏ cho con trỏ khác–Cho p chỉ tới vùng nhớ mà q đang chỉ
• Không được nhầm lẫn với:*p = *q;–Gán giá trị mà q đang chỉ đến cho biến (vùng nhớ) mà p đang chỉ đến
Lê Nguyên Khôi 13
Toán tử gán = - Ví dụ
• Có sự khác biệt rất quan trọng khi thực hiện các phép gán:
và
Lê Nguyên Khôi 14
0x15A4
0x15A0int i = 10, j = 14;int *p = &i;int *q = &j;
*p = *q;
int i = 10, j = 14;int *p = &i;int *q = &j;
*p = *q;
p i10
0x15A014
q j
0x15A414
0x15A414
0x15A0int i = 10, j = 14;int *p = &i;int *q = &j;
p = q;
int i = 10, j = 14;int *p = &i;int *q = &j;
p = q;
p i10
0x15A0q j
0x15A4
0x15A4
Luyện tập – Điền vào ô trống
Lê Nguyên Khôi 15
int main(void){
int i = 10, j = 14, k;int *p = &i;int *q = &j;
*p += 1;p = &k;*p = *q;p = q;*p = i;
return 0;}
int main(void){
int i = 10, j = 14, k;int *p = &i;int *q = &j;
*p += 1;p = &k;*p = *q;p = q;*p = i;
return 0;}
10i0x2100
14j0x2104
?k0x1208
0x2100p0x120B
q0x1210
0x2104
11
0x2108
14
Con Trỏ & Mảng• Biến kiểu mảng là địa chỉ tĩnh của một vùng nhớ, được
xác định khi khai báo, không thay đổi bao giờ thay đổi.• Biến con trỏ là địa chỉ động của một vùng nhớ, được xác
định qua phép gán địa chỉ khi chương trình thực thi.
Lê Nguyên Khôi 16
#include <stdio.h>int main(){
int a[10] = {1, 3, 4, 2, 0};int *p;p = a; //a = p: saiprintf(“0x%04X %i 0x%04X %i\n“,
a, a[0], p, *p);return 0;
}
#include <stdio.h>int main(){
int a[10] = {1, 3, 4, 2, 0};int *p;p = a; //a = p: saiprintf(“0x%04X %i 0x%04X %i\n“,
a, a[0], p, *p);return 0;
}
Toán tử + với số nguyên
Lê Nguyên Khôi 17
3344
0x15A20x15A2
#include <stdio.h>int main(){
short a[10] = {1, 3, 5, 2, 0};short *p = a; printf(“0x%04X %i 0x%04X %i\n“,
a, a[0], p, *p);p ++;printf(“0x%04X %i 0x%04X %i\n“,
a, a[0], p, *p);(*p) ++;printf(“0x%04X %i 0x%04X %i\n“,
a, a[0], p, *p);return 0;
}
#include <stdio.h>int main(){
short a[10] = {1, 3, 5, 2, 0};short *p = a; printf(“0x%04X %i 0x%04X %i\n“,
a, a[0], p, *p);p ++;printf(“0x%04X %i 0x%04X %i\n“,
a, a[0], p, *p);(*p) ++;printf(“0x%04X %i 0x%04X %i\n“,
a, a[0], p, *p);return 0;
}
11
55
22
00
aa
……
0x15A0
pp0x16B2
Con Trỏ - Luyện tập
Lê Nguyên Khôi 18
#include <stdio.h>int main(){
int a[10] = {2, 3, 5, 1, 4, 7, 0};int *p = a; printf(“%i %i\n“, a[0], *p);p ++;printf(“%i %i\n“, *p, p[2]);p ++; a[2] = 9;printf(“%i %i\n“, p[1], *p);p -= 2;printf(“%i %i\n”, p[3], p[1]);return 0;
}
#include <stdio.h>int main(){
int a[10] = {2, 3, 5, 1, 4, 7, 0};int *p = a; printf(“%i %i\n“, a[0], *p);p ++;printf(“%i %i\n“, *p, p[2]);p ++; a[2] = 9;printf(“%i %i\n“, p[1], *p);p -= 2;printf(“%i %i\n”, p[3], p[1]);return 0;
}
2 23 11 91 3
2 23 11 91 3
Cấp phát vùng nhớ đông• Có thể chỉ định vùng mới cho 1 con trỏ quản lý bằng các
lệnh hàm malloc.• Vùng nhớ do lập trình viên chỉ định phải được giải phóng
bằng lệnh free.
Lê Nguyên Khôi 19
#include <stdio.h>int main(){
int *p = (int*) malloc (sizeof(int) * 10);p[0] = 1;p[3] = -7;free(p);return 0;
}
#include <stdio.h>int main(){
int *p = (int*) malloc (sizeof(int) * 10);p[0] = 1;p[3] = -7;free(p);return 0;
}