Bài giảng Hệ thống máy tính và ngôn ngữ C - Chương 12: Pointer

12.1 Khái niệm

12.2 Thao tác trên POINTER

12.3 POINTER và mảng

12.4 Đối số của hàm là pointer -

truyền đối số theo số dạng tham

số biến

12.5 Hàm trả về pointer và

mảng

12.6 Chuỗi ký tự

12.7 Pointer và việc định vị

bộ nhớ động

12.8 Mảng các pointer

12.9 Pointer của pointer

12.10 Đối số của hàm MAIN

12.11 Pointer trỏ đến hàm

12.12 Ứng dụng

Bài tập cuối chương

 

pdf110 trang | Chuyên mục: C/C++ | Chia sẻ: yen2110 | Lượt xem: 473 | Lượt tải: 0download
Tóm tắt nội dung Bài giảng Hệ thống máy tính và ngôn ngữ C - Chương 12: Pointer, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
 chiều dài chuỗi 
#include 
#include 
#include 
main() 
{ char ten[41]; int i; clrscr(); 
 printf("Moi ban nhap ten: "); gets(ten); 
 for ( i = 0; i < strlen (ten); i++) 
 if (ten[i] >= 'a' && ten[i] <= 'z') ten[i] -= 32; 
 printf ("A! Chao ban: %s", ten); 
 getch();} 
CHƯƠNG 12 
POINTER 
12.6 CHUỖI KÝ TỰ 
5- Nối chuỗi 
Để nối hai chuỗi lại, C có hàm chuẩn strcat(). Hàm này 
nhận hai chuỗi làm đối số, và một bản sao của chuỗi thứ 
hai sẽ được chép nối vào cuối của chuỗi thứ nhất, để tạo ra 
chuỗi mới. Chuỗi thứ hai vẫn không có gì thay đổi. 
Prototype của hàm này trong file string.h: 
 char *strcat(char *dest, const char *src); 
Ví dụ 13.37(SGT) 
CHƯƠNG 12 
POINTER 
12.6 CHUỖI KÝ TỰ 
6- So sánh chuỗi 
Hàm này là strcmp(), có prototype trong file string.h: 
 int strcmp(const char *s1, const char*s2); 
Hàm này so sánh hai chuỗi s1 và s2 và trả về một trị là: 
- số dương nếu s1 > s2 
- số âm nếu s1 < s2 
- số 0 nếu s1 == s2 
CHƯƠNG 12 
POINTER 
12.6 CHUỖI KÝ TỰ 
6- So sánh chuỗi 
Ví dụ:Xét chương trình ví dụ sau đây 
#include 
#include 
#include 
main() 
{ clrscr(); 
 printf("%d \n", strcmp("QUAN", “quan”)); 
 printf("%d \n', strcmp("QUAN", "QUAN")); 
 printf("%d \n", strcmp("quan", "QUAN")); 
 printf("%d \n", strcmp("quang”, “quanG")); 
 printf("%d \n", strcmp("quang”, “quan")); getch();
 } 
CHƯƠNG 12 
POINTER 
12.6 CHUỖI KÝ TỰ 
6- So sánh chuỗi 
Chương trình cho xuất liệu: 
-32 
0 
32 
32 
103 
CHƯƠNG 12 
POINTER 
12.7 POINTER VÀ VIỆC ĐỊNH VỊ BỘ NHỚ ĐỘNG 
C cho phép khai báo các biến động, các biến này khi cần 
thì xin chỗ, không cần thì giải phóng vùng nhớ cho chương 
trình sử dụng vào mục đích khác. Các biến động này được 
cấp phát trong vùng nhớ heap, là vùng đáy bộ nhớ (vùng 
còn lại sau khi đã nạp các chương trình khác xong), và 
được quản lý bởi các biến pointer 
CHƯƠNG 12 
POINTER 
12.7 POINTER VÀ VIỆC ĐỊNH VỊ BỘ NHỚ ĐỘNG 
Trong C có hai hàm chuẩn để xin cấp phát bộ nhớ động 
malloc() và calloc(), cả hai hàm đều có prototype nằm 
trong file alloc.h hoặc stdlib.h như sau: 
 void *malloc(size_t size); 
 void *calloc(size_t nitems, size_t size); 
CHƯƠNG 12 
POINTER 
12.7 POINTER VÀ VIỆC ĐỊNH VỊ BỘ NHỚ ĐỘNG 
Nếu biến động được xin, sau khi dùng xong, vùng nhớ của 
nó không được giải phóng thì nó vẫn chiếm chổ trong bộ 
nhớ, mặc dù chương trình đã kết thúc. C đưa ra hàm free() 
để giải phóng khối bộ nhớ được xin bằng hàm malloc() 
hoặc calloc(). 
Prototype của hàm free() trong file stdlib.h hoặc alloc.h 
như sau: 
 void free (void * block); 
CHƯƠNG 12 
POINTER 
12.7 POINTER VÀ VIỆC ĐỊNH VỊ BỘ NHỚ ĐỘNG 
Cấu trúc bộ nhớ LC-3 
với ứng bộ nhớ heap 
CHƯƠNG 12 
POINTER 
12.7 POINTER VÀ VIỆC ĐỊNH VỊ BỘ NHỚ ĐỘNG 
Ví dụ: 
Cần xin một khối bộ nhớ có 10 phần tử int, ta viết như 
sau: 
 int *pint; 
 pint = (int *) malloc (10 * siezof (int)); 
hoặc 
 pint = (int *) calloc (10, siezof (int)); 
CHƯƠNG 12 
POINTER 
12.7 POINTER VÀ VIỆC ĐỊNH VỊ BỘ NHỚ ĐỘNG 
Ví dụ: 
#include 
#include 
#include  EXIT 
#include 
main() 
{ int *pint, s = 0, i; 
 pint = (int *) calloc (10, sizeof (int)); 
 if (pint == NULL) 
 { printf ("Khong du bo nho \n"); 
 exit (1); } 
CHƯƠNG 12 
POINTER 
12.7 POINTER VÀ VIỆC ĐỊNH VỊ BỘ NHỚ ĐỘNG 
Ví dụ: 
 clrscr(); 
 printf ("Moi nhap 10 tri vao mang: "); 
 for (i = 0; i <10; i++) 
 scanf ("%d", &pint[i]); 
 for (i = 0; i <10; i++) 
 s += pint[i]; 
 printf ("Tong cac phan tu cua mang la: %d \n", s); 
 getch(); 
 free (pint); 
} 
CHƯƠNG 12 
POINTER 
12.8 MẢNG CÁC POINTER 
Cú pháp khai báo mảng các pointer: 
 kiểu * tên_mảng [Kích_thước]; 
Ví dụ: Khi khai báo 
 int * pint[4]; 
CHƯƠNG 12 
POINTER 
12.8 MẢNG CÁC POINTER 
Ví dụ: Khi khai báo 
 int * pint[4]; 
 int a = 2, b = 3, c = 4, d = 5; 
 pint[0] = &a; 
 pint[1] = &b; 
 pint[2] = &c; 
 pint[3] = &d; 
CHƯƠNG 12 
POINTER 
12.8 MẢNG CÁC POINTER 
CHƯƠNG 12 
POINTER 
12.8 MẢNG CÁC POINTER 
Ví dụ: Khi khai báo 
 int * pint[4]; 
 int a[3], b[3], c[3], d[3]; 
 pint[0] = a; 
 pint[1] = b; 
 pint[2] = c; 
 pint[3] = d; 
CHƯƠNG 12 
POINTER 
12.8 MẢNG CÁC POINTER 
CHƯƠNG 12 
POINTER 
12.8 MẢNG CÁC POINTER 
Ví dụ 13.48, 13.49 (SGT) 
Ví dụ : Khi khai báo 
int a[4][5]; 
int *b[4]; 
thì khi truy xuất a[2][3] và b[2][3], C đều hiểu đây là các 
biến int 
CHƯƠNG 12 
POINTER 
12.8 MẢNG CÁC POINTER 
Một mảng các pointer cũng có thể được khởi động trị nếu 
mảng là mảng toàn cục hay mảng tĩnh. 
Ví dụ: 
static char *thu[7] = {"Thu 2", "Thu 3", "Thu 4", "Thu 
5", "Thu 6", "Thu 7", "Chua nhat"}; 
CHƯƠNG 12 
POINTER 
12.9 POINTER CỦA POINTER 
Cú pháp khai báo pointer này như sau: 
 kiểu ** tên_pointer 
Ví dụ: 
 int **pint; 
 int*p; 
 int a[4][4]; 
thì pint = &p; 
hoặc pint = (int **) &a; 
CHƯƠNG 12 
POINTER 
12.9 POINTER CỦA POINTER 
CHƯƠNG 12 
POINTER 
Thay vì truy xuất 
a[i][j], ta có thể 
truy xuất 
*(pint + m*i + j), 
với m là số phần 
tử trên một hàng 
của mảng hai 
chiều. 
12.9 POINTER CỦA POINTER 
Ví dụ: 
#include 
#define MAX_ROW 3 
#define MAX_COL 3 
main() 
{ int row, col; 
 int *pint1; 
 int a2d [MAX_ROW][MAX_COL] = { {0, 1, 2}, 
 {10, 11, 12}, 
 {20, 21, 22} }; 
CHƯƠNG 12 
POINTER 
12.9 POINTER CỦA POINTER 
 int **pint2; 
 int (*pa2d)[MAX_ROW][MAX_COL]; 
 /* Thu dia chi cua pointer va mang 2 chieu */ 
 pint1 = a2d[1]; 
 pa2d = &a2d; 
 pint2 = (int **)&a2d; 
 printf ("pint1 = a2d[1] = %p\n", pint1); 
 printf ("*( *( ( int (*)[MAX_COL] ) pint2 + 1)+ 2)= 
 %d\n", *( *( ( int (*)[MAX_COL] ) pint2 + 1)+ 2)); 
 printf ("*( *(a2d + 1) + 2) = %d\n", *( *(a2d + 1) + 2)); 
CHƯƠNG 12 
POINTER 
12.9 POINTER CỦA POINTER 
 printf ("*pint1[2] = %d\n", pint1[2]); 
 printf ("(*pa2d)[1][2] = %d\n", (*pa2d)[1][2]); 
 printf ("Tri cua cac phan tu trong mang truy xuat qua 
 pointer 2 lan:\n"); 
 for (row = 0; row < MAX_ROW; row ++) 
 { for (col = 0; col < MAX_COL; col ++) 
 printf ("%d ", *( *( ( int (*)[MAX_COL] ) pint2 + 
 row)+ col)); 
 printf ("\n"); } 
 getchar();} 
CHƯƠNG 12 
POINTER 
12.9 POINTER CỦA POINTER 
CHƯƠNG 12 
POINTER 
12.9 POINTER CỦA POINTER 
Ví dụ : 
int *m[4]; 
int a = 1, b = 2, c = 3, d = 4; int **pint; 
pint = m; 
m[0] = &a; m[1] = &b; m[2] = &c; m[3] = &d; 
Thay vì truy xuất trực tiếp a, b, ..., ta có thể dùng pointer 
*(pint[i]) 
CHƯƠNG 12 
POINTER 
12.9 POINTER CỦA POINTER 
Ví dụ: Xét khai báo sau: 
int ** pi; 
int * pint[4]; 
int a[3], b[3], c[3], d[3]; 
pi = pint; 
pint[0] = a; pint[1] = b; pint[2] = c; pint[3] = d; 
CHƯƠNG 12 
POINTER 
12.9 POINTER CỦA POINTER 
CHƯƠNG 12 
POINTER 
12.9 POINTER CỦA POINTER 
Ví dụ 13.56(GT) 
CHƯƠNG 12 
POINTER 
12.10 ĐỐI SỐ CỦA HÀM MAIN 
C hoàn toàn cho phép việc nhận đối số vào hàm main(), có 
hai đối số C đã quy định theo thứ tự: 
int agrc: đối số cho biết số tham số đã nhập, kể cả tên 
chương trình. 
char *argv[]: mảng các pointer trỏ đến các chuỗi là tham 
số đi theo sau tên chương trình khi chạy chương trình từ 
DOS. 
CHƯƠNG 12 
POINTER 
12.10 ĐỐI SỐ CỦA HÀM MAIN 
Ví dụ: Xét chương trình ví dụ sau: 
#include 
#include 
main (int argc, char *argv[]) 
{ int i; 
 clrscr(); 
 printf ("Cac doi so cua chuong trinh la: \n"); 
 printf ("Ten chuong trinh la: %s \n", argv[0]); 
 if ( argc >1 ) 
 for (i = 1; i < argc; i++) 
 printf ("Doi so thu %d: %s \n", i, 
argv[i]); 
 getch(); } 
CHƯƠNG 12 
POINTER 
12.10 ĐỐI SỐ CỦA HÀM MAIN 
Nếu nhập từ bàn phím như sau 
 C:\>thu_main tin thu 123 
thì chương trình cho xuất liệu là: 
 Cac doi so cua chuong trinh la: 
 Ten chuong trinh la: C:\thu_main.exe 
 Doi so thu 1: tinDoi so thu 2: thu 
 Doi so thu 3: 123 
Ví dụ 13.59(GT) 
CHƯƠNG 12 
POINTER 
12.11 POINTER TRỎ ĐẾN HÀM 
Cú pháp khai báo một pointer chỉ tới hàm: 
 kiểu (* tên_pointer) (kiểu_các_đối_số); 
Chú ý: 
 kiểu * tên_hàm (kiểu_các_đối_số);Hàm trả về 
pointer 
CHƯƠNG 12 
POINTER 
12.11 POINTER TRỎ ĐẾN HÀM 
Ví dụ: 
Nếu khai báo int (* p_function) (int, int); 
và đã có hàm 
 int cong (int a, int b) 
 { ... 
 } 
Ta có thể: 
 p_function = cong; 
 tong = (*p_function) (m, n); 
CHƯƠNG 12 
POINTER 
12.11 POINTER TRỎ ĐẾN HÀM 
Ví dụ 13.62 (GT) 
CHƯƠNG 12 
POINTER 
12.12 ỨNG DỤNG 
12.12.1 Danh sách liên kết là stack 
12.12.2 Danh sách liên kết là queue 
(GT) 
CHƯƠNG 12 
POINTER 
12.12 ỨNG DỤNG 
BÀI TẬP CUỐI CHƯƠNG 
1. Viết chương trình với một hàm cho phép truy xuất chuỗi 
trong stack (danh sách liên kết và mảng) và in ra màn 
hình thông tin theo thứ tự alphabet. 
2. Dùng cấu trúc dữ liệu queue dạng danh sách liên kết, 
tính biểu thức dạng đa thức bất kỳ sau: 
f(x) = 
trong phần thông tin có hai vùng biến 
- hệ số 
- số mũ 
CHƯƠNG 12 
POINTER 
...n m 3
o 1 n 1 n
a x a x a x a   
12.12 ỨNG DỤNG 
BÀI TẬP CUỐI CHƯƠNG 
3. Viết chương trình với một hàm duyệt toàn bộ các phần 
tử trong queue, trả về số phần tử trong queue. 
4. Viết chương trình tạo một danh sách liên kết lưu các 
thông tin là các số nguyên theo thứ tự từ lớn tới nhỏ. 
Thiết kế hàm insert() cho phép chèn một phần tử lưu 
thông tin số vào vị trí có thứ tự phù hợp trong chuỗi. 
5. Viết chương trình nhập vào một số số nguyên (chưa biết 
có bao nhiêu số nguyên). Loại bỏ cácsố nguyên bị lặp lại. In 
ra dãy số mới này. 
Ví dụ: Nhập: 5 4 10 8 5 4 10 2 8 In ra: 5 4 10 8 2 
CHƯƠNG 12 
POINTER 
 KẾT THÚC CHƯƠNG 12 
CHƯƠNG 12 
POINTER 

File đính kèm:

  • pdfbai_giang_he_thong_may_tinh_va_ngon_ngu_c_chuong_12_pointer.pdf