V - Về con trỏ hàm trong C
A. Giới thiệu
Con trỏ hàm là một trong những tính năng mạnh mẽ của ngôn ngữ lập trình C, cho phép ta truyền một hàm như một tham số cho một hàm khác. Điều này giúp tăng tính linh hoạt của chương trình và cho phép các hàm có thể được tái sử dụng nhiều lần. Trong bài viết này, chúng ta sẽ tìm hiểu về con trỏ hàm trong C.
B. Cấu trúc của con trỏ hàm
Con trỏ hàm là một biến chứa địa chỉ của một hàm. Để khai báo một con trỏ hàm, ta sử dụng cú pháp sau:
<kiểu trả về> (*<tên con trỏ>)(<danh sách tham số>);
Ví dụ, để khai báo một con trỏ hàm có kiểu trả về là int và có một tham số kiểu int, ta sử dụng cú pháp sau:
int (*ptr)(int);
C. Sử dụng con trỏ hàm
Gán địa chỉ của một hàm cho con trỏ hàm
Để gán địa chỉ của một hàm cho con trỏ hàm, ta sử dụng tên của hàm mà không có dấu ngoặc đơn.
Ví dụ:
int add(int a, int b) {
return a + b;
}
int main() {
int (*ptr)(int, int);
ptr = add;
return 0;
}
Gọi hàm thông qua con trỏ hàm
Để gọi một hàm thông qua con trỏ hàm, ta sử dụng toán tử "dereference
" (*).
Ví dụ:
int add(int a, int b) {
return a + b;
}
int main() {
int (*ptr)(int, int);
ptr = add;
int sum = (*ptr)(2, 3);
printf("%d", sum); // output: 5
return 0;
}
Truyền con trỏ hàm như một tham số cho một hàm khác
Việc truyền con trỏ hàm như một tham số cho một hàm khác cho phép ta truyền một hàm như một đối số cho một hàm khác.
Ví dụ:
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
void doMath(int (*math)(int, int), int a, int b) {
int result = (*math)(a, b);
printf("%d", result);
}
int main() {
doMath(add, 2, 3); // output: 5
doMath(subtract, 2, 3);
}
Truyền con trỏ hàm như một tham số cho một hàm khác là một kỹ thuật rất phổ biến trong C để xử lý các tác vụ trừu tượng và tái sử dụng code. Khi truyền một con trỏ hàm như một tham số cho một hàm khác, ta cho phép hàm đó sử dụng một hàm khác như một tham số của nó. Điều này cho phép ta tạo ra các hàm có khả năng tái sử dụng và linh hoạt hơn.
Cú pháp để truyền con trỏ hàm là khai báo kiểu con trỏ hàm và sử dụng nó làm tham số của hàm. Đây là một ví dụ đơn giản về cách truyền con trỏ hàm như một tham số cho một hàm khác:
#include <stdio.h>
void message(char *str) {
printf("%s\n", str);
}
void wrapper(void (*func)(char *)) {
printf("Before the function call.\n");
func("Inside the function call.");
printf("After the function call.\n");
}
int main() {
wrapper(message);
return 0;
}
Trong ví dụ này, ta có hai hàm: message
và wrapper
. Hàm message
chỉ đơn giản in một thông điệp ra màn hình. Hàm wrapper
nhận một con trỏ hàm làm tham số và sử dụng nó để gọi hàm message
bên trong nó. Sau đó, nó in ra một số thông điệp khác.
Ở trong hàm main, ta gọi hàm wrapper
và truyền con trỏ hàm message làm tham số. Như vậy, hàm wrapper
được gọi và sử dụng con trỏ hàm message
để in ra thông điệp. Kết quả khi chạy chương trình sẽ là:
Before the function call.
Inside the function call.
After the function call.
Như vậy, ta đã sử dụng kỹ thuật truyền con trỏ hàm để tạo ra một hàm wrapper
có khả năng tái sử dụng và linh hoạt hơn.