Trước khi tìm hiểu mảng con trỏ, chúng ta xét vài ví dụ để hiểu được vì sao mảng con trỏ là cần thiết trong ngôn ngữ lập trình C.
Ví dụ 1: sắp xếp chuỗi theo thứ tự alpha, beta,..
#include <stdio.h> #include <string.h> #include <conio.h> #define LENGTH 30 void strsort(char str[][LENGTH], int num); void strshow(char str[][LENGTH], int num); void main( void ) { char strarr[][LENGTH] = {"C/C++", "Java", "C#", "Python", "PHP", "Java Script"}; strsort(strarr, 6); strshow(strarr, 6); getch(); } void strsort(char str[][LENGTH], int num) { int i, j; char temp[LENGTH]; for (i = 0; i < num; i++) { for (j = num-1; j > i; j--) { if(strcmp(str[j], str[j-1]) < 0) { strcpy(temp, str[j]); strcpy(str[j], str[j-1]); strcpy(str[j-1], temp); } } } } void strshow(char str[][LENGTH], int num) { int i; for (i = 0; i < num; i++) { printf("\nstr[%d] = %s", i+1, str[i]); } }
Kết quả:
Qua ví dụ ở trên, chúng ta thấy để sắp xếp 1 mảng các chuỗi yêu cầu swap các chuỗi với nhau ( sử dụng hàm strcpy( ) hoán đổi nội dung giữa các chuỗi với nhau). Khi gặp các bài toán với kích thước dữ liệu lớn (chuỗi, struct,…), việc copy dữ liệu làm giảm performance của chương trình.
→ Dùng con trỏ trỏ tới vùng nhớ của dữ liệu (chuỗi, struct,…), sau đó swap con trỏ.
Ví dụ 2:
void main( void ) { int n = 6, m = 8; int *p1, *p2, *p; p1 = &n; p2 = &m; //swap p1 and p2 p = p1; p1 = p2; p2 = p; printf("\nn = %d", *p1); printf("\nm = %d", *p2); getch(); }
Kết quả:
Ở đây, chúng ta sử dụng 2 con trỏ p1 và p2 trỏ tới địa chỉ biến n và m. Thay vì hoán vị trực tiếp 2 biến n và m, chúng ta có thể hoán vị con trỏ p1 và p2. Từ ý tưởng này, chúng ta có thể sử dụng con trỏ để hoán vị 2 chuỗi cho nhau. Các bạn xem tiếp ví dụ sau:
Ví dụ 3: hoán vị 2 chuỗi
#include <stdio.h> #include <conio.h> void main( void ) { char s1[] = "vncoding.net"; char s2[] = "congdongcviet.com"; char *p1, *p2, *p; p1 = s1; p2 = s2; printf("\ns1 = %s", p1); printf("\ns2 = %s", p2); printf("\nswapping....."); //swap 2 strings p = p1; p1 = p2; p2 = p; printf("\ns1 = %s", p1); printf("\ns2 = %s", p2); getch(); }
Kết quả:
Con trỏ p1, p2 trỏ tới chuỗi s1, s2 tương ứng. Để đổi chỗ 2 chuỗi, chúng ta hoán vị 2 con trỏ.
Tổng kết lại, chúng ta có thể sử dụng mảng con trỏ để trỏ tới các phần tử trong mảng dữ liệu (string, struct,…) tương ứng. Việc sắp xếp các phần tử trong mảng dữ liệu (string, struct,…) dựa vào việc hoán vị các con trỏ. Mảng con trỏ sẽ lưu kết quả sắp xếp mảng (các phần tử mảng dữ liệu thực tế không được hoán vị).
Việc hoán vị con trỏ tăng performance của chương trình so với cách truyền thống như ở ví dụ 1
Chúng ta xét ví dụ tiếp theo về cách khai báo và sử dụng mảng con trỏ để sắp xếp mảng chuỗi kí tự.
Ví dụ 4:
#include <stdio.h> #include <string.h> #include <conio.h> #define LENGTH 30 #define SIZE 10 void strsort(char** str, int num); void strshow(char** str, int num); void main( void ) { char strarr[][LENGTH] = {"C/C++", "Java", "C#", "Python", "PHP", "Java Script"}; char* pstr[SIZE]; int i; for (i = 0; i < 6; i++) { pstr[i] = strarr[i]; } strsort(pstr, 6); strshow(pstr, 6); getch(); } void strsort(char** str, int num) { int i, j; char* temp; for (i = 0; i < num; i++) { for (j = num-1; j > i; j--) { if(strcmp(str[j], str[j-1]) < 0) { temp = str[j]; str[j] = str[j-1]; str[j-1] = temp; } } } } void strshow(char** str, int num) { int i; for (i = 0; i < num; i++) { printf("\nstr[%d] = %s", i+1, str[i]); } }
Giải thích:
for (i = 0; i < 6; i++) { pstr[i] = strarr[i]; }
Gán phần tử mảng con trỏ trỏ tới mỗi chuỗi trong mảng chuỗi.
if(strcmp(str[j], str[j-1]) < 0) { temp = str[j]; str[j] = str[j-1]; str[j-1] = temp; }
Hoán vị con trỏ. Sau khi thực hiện xong hàm strsort(). Giá trị mảng con trỏ như sau:
Kết quả mảng con trỏ lưu kết quả sắp xếp. Do vậy, mọi thao tác: hiển thị thông tin mảng được sắp xếp ra màn hình, ghi ra file đều được xử lí trên mảng con trỏ.
Leave a Reply
You must be logged in to post a comment.