Ếu cmp trỏ tới hàm sosahtd thì sắp xếp tăg dầ theo tuyệt đối */

Một phần của tài liệu Bài giảng ngôn ngữ lập trình C (Trang 48 - 50)

đó người ta gọi nó là con trỏ hàm. Một con trỏ hàm dùng để trỏ tới một tập các hàm có cùng nguyên mẫu về tham số và kiểu dữ liệu trả về. Sau khi một con trỏ hàm đã được xác lập trỏ đến một hàm cụ thể nào đó thì ta có thể gọi hàm đó thơng qua con trỏ hàm.

Dạng thức khai báo con trỏ hàm:

<kiểu hàm trả về> (* <con trỏ hàm>)(<tham số hàm>);

Ví dụ:

/* nguyên mẫu hàm so sánh hai số nguyên */ int sosanh(int, int);

/* nguyên mẫu hàm so sánh giá trị tuyệt đối hai số nguyên */ int sosanhtd(int, int);

/* con trỏ hàm cho nguyên mẫu giống như hai hàm so sánh */ int (*tro_sosanh) (int, int);

/* con trỏ hàm xác lập trỏ đến hàm so sánh thường */ tro_sosanh = sosanh;

tro_sosanh(-5, 4); /* gọi hàm qua con trỏ hàm, cho kết quả = -1 */ /* con trỏ hàm xác lập trỏ đến hàm so sánh tuyệt đối */

tro_sosanh = sosanhtd;

tro_sosanh(-5, 4); /* gọi hàm qua con trỏ hàm, cho kết quả = 1 */

Cần phân biệt giữa khai báo con trỏ hàm và khai báo nguyên mẫu hàm. Ví dụ:

int (*func_ptr)(int, int); /* khai báo một con trỏ hàm */ int * func(int, int); /* khai báo nguyên mẫu cho hàm func */

Chương trình mẫu (troham.c): Sắp xếp một dãy số nguyên nhập vào theo giá trị tăng dần và

theo tuyệt đối tăng dần. #include <stdio.h> #include <stdlib.h>

/* hàm so sánh 2 số theo giá trị */ int sosanh(int, int);

/* hàm so sánh 2 số theo tuyệt đối */ int sosanhtd(int, int);

/* sắp xếp dãy số với

p: là con trỏ đến phần tử đầu tiên n: là số phần tử n: là số phần tử

cmp: là con trỏ đến hàm so sánh hai số

nếu cmp trỏ tới hàm sosanh thì sắp xếp tăng dần theo giá trị

nếu cmp trỏ tới hàm sosanhtd thì sắp xếp tăng dần theo tuyệt đối */ */

void sapxep(int * p, int n, int (*cmp)(int, int) );

{

int n, i, dayso[100];

printf("So phan tu cua day so: "); scanf("%d", &n);

for (i=0; i<n; i++) {

printf("So thu %d: ", i+1); scanf("%d", &dayso[i]); }

printf("Day so duoc sap xep theo gia tri tang dan:\n"); sapxep(dayso, n, sosanh);

for (i=0; i<n; i++) printf("%5d ", dayso[i]);

printf("\nDay so duoc sap xep theo gia tri tuyet doi tang dan:\n"); sapxep(dayso, n, sosanhtd);

for (i=0; i<n; i++) printf("%5d ", dayso[i]); }

int sosanh(int a, int b)

{ /* trả về 0 nếu a=b, -1 nếu a<b và 1 nếu a>b */ if (a==b) return 0;

return a > b ? 1: -1; }

int sosanhtd(int a, int b)

{ /* trả về 0 nếu |a|=|b|, -1 nếu |a|<|b| và 1 nếu |a|>|b| */ if (abs(a)==abs(b)) return 0;

return abs(a) > abs(b) ? 1: -1; }

void sapxep(int * p, int n, int (*cmp)(int, int) ) {

int i, j, tg;

for (i=0; i<n-1; i++) for(j=i+1; j<n; j++)

/* so sánh hai số theo con trỏ hàm, đổi chỗ nếu cần thiết */ if(cmp(p[i], p[j])>0) { /* đổi chỗ 2 phần tử */ tg = p[i]; p[i] = p[j]; p[j] = tg; } }

Một trong những ứng dụng mạnh của con trỏ hàm là để tạo ra các giải thuật tổng quát trên mọi loại dữ liệu. Trong thư viện <stdlib.h> có hai hàm qsort() và bsearch() dùng để sắp xếp và tìm kiếm trên một mảng dữ liệu bất kì.

void qsort(void *base, size_t num, size_t size, int (*compare)(void const *, void const *)); void *bsearch(const void *key, const void *base, size_t num, size_t size,

int (*compare)(const void *, const void *));

Trong đó:

- base là địa chỉ của mảng dữ liệu cần sắp xếp hoặc để tìm kiếm - num là số phần tử của mảng

- size là kích thước bộ nhớ của một phần tử

- compare là con trỏ đến một hàm so sánh hai phần tử, hàm này nhận tham số vào là địa chỉ của 2 phần tử cần so sánh

- key là địa chỉ của một phần tử mang giá trị cần tìm kiếm, kết quả trả về của hàm bsearch() là con trỏ đến phần tử tìm thấy trong mảng

Xem thêm bài 28 (Truyền tham biến cho hàm) để biết ý nghĩa sử dụng của từ khoá const đối với các tham số của hàm.

Ví dụ:

/* hàm so sánh 2 số nguyên theo nguyên mẫu con trỏ hàm của qsort() */ int sosanhso(void const* x, void const*y)

{ int m, n; int m, n; m = *(int*)x; /* lấy giá trị của số thứ 1 */ n = *(int*)y; /* lấy giá trị của số thứ 2 */ if (m==n) return 0; return m > n ? m: n; } void main() { int a[20], n; /* nhập dãy số vào mảng */ /* sắp xếp mảng bằng qsort */

qsort(a, n, sizeof(int), sosanhso); }

BÀI TẬP

Câu 1: Dùng hàm qsort() để viết chương trình sắp xếp một mảng số thực nhập vào theo hai cách:

giá trị tăng dần và giá trị tuyệt đối tăng dần.

Câu 2: Bằng cách tương tự như hàm sắp xếp tổng quát một dãy số nguyên trong chương trình

mẫu, hãy viết một hàm tổng quát để chèn một số nguyên vào một dãy số đã sắp xếp theo một trật tự nào đó.

Một phần của tài liệu Bài giảng ngôn ngữ lập trình C (Trang 48 - 50)