logo

Tìm hiểu về Lập Trình C

V - Về con trỏ hàm trong C

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: messagewrapper. 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.