Menu
CoddyTech

Gọi con trỏ hàm

Thuộc phần Lập trình hướng đối tượng trong hành trình C của Coddy. Bài học 34 trên 61.

Bây giờ bạn đã biết cách khai báo con trỏ hàm và gán một hàm cho nó, bước tiếp theo là thực sự gọi hàm thông qua con trỏ đó.

Cú pháp khá đơn giản. Bạn dùng con trỏ hàm (function pointer) giống như khi gọi một hàm thông thường:

int add(int a, int b) {
    return a + b;
}

int main() {
    int (*operation)(int, int) = add;
    
    int result = operation(5, 3);  // Gọi add(5, 3)
    printf("%d\n", result);        // Đầu ra: 8
    return 0;
}

Chỉ cần viết tên con trỏ, theo sau là dấu ngoặc đơn chứa các đối số. C tự động giải tham chiếu con trỏ và thực thi hàm mà nó trỏ đến.

Bạn cũng có thể dùng cú pháp giải tham chiếu tường minh với (*operation)(5, 3), nhưng đây là cách không bắt buộc và ít phổ biến hơn. Cả hai cách đều cho kết quả giống hệt nhau.

Sức mạnh thực sự thể hiện khi bạn gán lại con trỏ cho các hàm khác nhau:

int subtract(int a, int b) {
    return a - b;
}

operation = subtract;
result = operation(5, 3);  // Bây giờ gọi subtract(5, 3)
printf("%d\n", result);    // Đầu ra: 2

Biến operation giờ thực thi logic hoàn toàn khác. Khả năng thay đổi hành vi khi chương trình đang chạy này là nền tảng của tính đa hình trong C.

challenge icon

Thử thách

Dễ

Hãy luyện tập cách gọi hàm thông qua con trỏ và thay đổi hàm sẽ được thực thi. Bạn sẽ xây dựng một máy tính đơn giản có thể chuyển đổi giữa phép cộng và phép trừ khi chương trình đang chạy.

Viết một chương trình:

  1. Định nghĩa hai hàm:
    • add: nhận hai tham số int và trả về tổng của chúng
    • subtract: nhận hai tham số int và trả về hiệu của số thứ nhất trừ số thứ hai
  2. Trong main, khai báo một con trỏ hàm có tên calc, có thể trỏ đến các hàm nhận hai tham số int và trả về một int
  3. Đọc bốn đầu vào: hai số nguyên và hai mã phép toán
  4. Với mỗi mã phép toán:
    • Gán hàm phù hợp cho calc (1 cho phép cộng, 2 cho phép trừ)
    • Gọi hàm thông qua con trỏ với hai số
    • In ra kết quả

Bạn sẽ nhận bốn đầu vào: số thứ nhất, số thứ hai, mã phép toán thứ nhất (1 hoặc 2) và mã phép toán thứ hai (1 hoặc 2).

Đầu ra cần hiển thị hai kết quả trên hai dòng riêng: mỗi kết quả ứng với một phép toán được thực hiện bằng cùng hai số:

15
5

Trong ví dụ này, với các đầu vào 10, 5, 1, 2: phép toán thứ nhất (mã 1) cộng 10 + 5 = 15, sau đó con trỏ được gán lại và phép toán thứ hai (mã 2) trừ 10 - 5 = 5.

Điều này cho thấy cùng một biến con trỏ có thể thực thi logic hoàn toàn khác nhau khi bạn gán lại nó giữa các lần gọi.

Tự làm thử

#include <stdio.h>

// TODO: Định nghĩa hàm (function) add tại đây


// TODO: Định nghĩa hàm subtract tại đây


int main() {
    // Đọc các giá trị đầu vào
    int num1, num2, op1, op2;
    scanf("%d", &num1);
    scanf("%d", &num2);
    scanf("%d", &op1);
    scanf("%d", &op2);
    
    // TODO: Khai báo con trỏ hàm tên 'calc' có thể trỏ đến
    // các hàm nhận hai tham số kiểu int và trả về một giá trị kiểu int
    
    
    // TODO: Với mã phép toán đầu tiên (op1):
    // - Gán hàm phù hợp cho calc (1 là add, 2 là subtract)
    // - Gọi hàm qua con trỏ và in kết quả
    
    
    // TODO: Với mã phép toán thứ hai (op2):
    // - Gán lại hàm phù hợp cho calc
    // - Gọi hàm qua con trỏ và in kết quả
    
    
    return 0;
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch C online