Chương 8 Con trỏ Pointer Presenter:... Learning outcomes L.O.6.1 – Khai báo được con trỏ... Pointer và cấp phát động Hiện thực Sau khi có con trỏ đến ma trận, để có ma trận
Trang 1Chương 8
Con trỏ (Pointer)
Presenter:
Trang 2Learning outcomes
L.O.6.1 – Khai báo được con trỏ
L.O.6.2 – Truy xuất được dữ liệu qua con trỏ
L.O.6.3 – Giải thích được cách cấp phát bộ nhớ động
L.O.6.4 – Sử dụng được các phép toán trên con trỏ
L.O.6.5 – Sử dụng được con trỏ của con trỏ khác
L.O.6.6 – Dùng được con trỏ với kiểu cấu trúc
L.O.6.7 – Hiểu được sự liên quan giữa con trỏ và mảng
Trang 3Kiểu con trỏ (pointer)
Định nghĩa
Kiểu con trỏ là kiểu biến đặc biệt chỉ dùng để giữ địa chỉ (tham khảo) Dùng dấu * để định nghĩa
Ví dụ:
Toán tử '&' cho phép gán địa chỉ của một biến vào con trỏ như sau :
<con trỏ> = &<tên biến>
Ví dụ :
Kiểu con trỏ là kiểu biến đặc biệt chỉ dùng để giữ địa chỉ (tham khảo) Dùng dấu * để định nghĩa
Ví dụ:
Toán tử '&' cho phép gán địa chỉ của một biến vào con trỏ như sau :
<con trỏ> = &<tên biến>
Ví dụ :
Con trỏ biến được dùng lưu giữ địa chỉ các biến và cho
Trang 4Kiểu con trỏ (pointer)
Ví dụ 1
Trang 5Con trỏ biến cấu trúc
Tham số hàm kiểu con trỏ cấu trúc
Trang 6Pointer và cấp phát động
Ý tưởng
Kiểu pointer rất thích hợp để quản lý dữ liệu có độ lớn chưa biết trước tại thời điểm lập trình
Ví dụ :
double param[100][100]; // cấp phát 10.000 phần tử kiểu double
hay
double** param; // chỉ cấp phát 1 pointer
(double**)
(double*)
(double)
Trang 7Pointer và cấp phát động
Hiện thực
Sau khi có con trỏ đến ma trận, để có ma trận thực sự, ta dùng hàm malloc (memory allocation) trong thư viện malloc.lib (#include malloc.h) để sinh ra các vector và phần tử
Ví dụ :
• Sinh ra m vector (m chưa biết trước)
printf ("Nhap M: "); scanf_s("%d", &m);
param = (double**) malloc (m * sizeof(double*));
• Sinh ra n phần tử trong mỗi vector (n chưa biết trước)
printf ("Nhap N: "); scanf_s("%d", &n);
for (i = 0; i < m; i++)
param[i] = (double*) malloc (n * sizeof(double));
Chú ý toán tử sizeof(kiểu) trả về kích thước kiểu cần cấp phát trong bộ nhớ
Trang 8Pointer và cấp phát động
Ví dụ
Trang 9Ví dụ thêm về con trỏ
int* pi; // pointer to int
char** ppc ; // pointer to pointer to char
int* ap [15]; // array of 15 pointers to ints
int (* fp )(char*); // pointer to function taking a char*
// argument; returns an int
int* f (char*); // function taking a char* argument;
// returns a pointer to int
Trang 10Pointers to strings
Đúng hay sai ?
char *psz;
psz = “File not ready”;
char *psz = “File not ready”;
char pszarray[ ] = “Drive not ready”;
char pszarray[16];
pszarray = “Drive not ready”;
char *psz;
Trang 11Pointer arithmetic and arrays
Ví dụ 1
Trang 12Pointer arithmetic and arrays
Ví dụ 2
Trang 13Con trỏ và hằng
void f1 (char *p)
{ char s[] = "Gorm";
const char* pc=s ; // con trỏ đến một hằng
pc[3]= ´g´; // sai : không thể thay đổi nội dung
pc=p; // ok: có thể thay đổi địa chỉ
char *const cp=s; // hằng con trỏ
cp[3]= ´a´; // ok: có thể thay đổi nội dung
cp=p; // sai : không thể thay đổi địa chỉ
const char *const cpc=s; // hằng con trỏ đến một hằng
cpc[3]= ´a´; // sai : không thể thay đổi nội dung
cpc=p ; // sai : lẫn địa chỉ
Trang 14Phép toán trên pointer
Kết quả nhận được là gì ?
Thường dùng (pointer + integer)
Có thể trừ số nguyên vào con trỏ (pointer - integer)
Có thể trừ hai con trỏ (pointer - pointer)
Có thể so sánh hai con trỏ với nhau (<=, =, >=)
Trang 15
Con trỏ đến hàm
Trang 16Dãy con trỏ hàm
Khái niệm
Dãy con trỏ hàm thích hợp với các bài toán xử lý theo sơ đồ chuyển trạng thái
00
Gọi hàm xuly[0] ()
Nhập số N
In kết quả Tính
toán
Trang 17Dãy con trỏ hàm
Ví dụ
Sửa lại hàm tinhdiem_tk() để dùng dãy con trỏ hàm
Chương trình dùng dãy con trỏ hàm