Menu
CoddyTech

Truyền hàm làm đối số

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 36 trên 61.

Một trong những cách sử dụng con trỏ hàm (function pointer) hiệu quả nhất là truyền chúng làm đối số cho các hàm khác. Cách này cho phép bạn thêm hành vi tùy chỉnh vào một hàm mà không cần sửa code của hàm đó, đây là kỹ thuật đôi khi được gọi là callback.

Hãy xem xét một hàm thực hiện phép tính trên hai số. Thay vì viết cứng phép toán, bạn có thể nhận một con trỏ hàm xác định phép toán cần thực hiện:

typedef int (*Operation)(int, int);

int compute(int a, int b, Operation op) {
    return op(a, b);
}

Hàm compute không biết mình đang cộng, trừ hay làm việc gì khác. Hàm chỉ gọi hàm được truyền vào:

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

int main() {
    printf("%d\n", compute(5, 3, add));       // Đầu ra: 8
    printf("%d\n", compute(5, 3, multiply));  // Đầu ra: 15
    return 0;
}

Hãy chú ý rằng cùng một hàm compute tạo ra các kết quả khác nhau tùy vào hàm mà ta truyền vào. Mẫu này là nền tảng để viết code linh hoạt và có thể tái sử dụng. Bạn viết cấu trúc một lần, rồi người dùng hàm của bạn cung cấp logic cụ thể mà họ cần.

challenge icon

Thử thách

Dễ

Viết hàm apply_twice nhận hai số nguyên và một mã thao tác, áp dụng thao tác đó lần lượt lên các số hai lần rồi trả về kết quả cuối cùng.

Hàm của bạn sẽ nhận một mã thao tác để xác định thao tác cần dùng. Bạn cần định nghĩa các hàm thao tác bên trong lời giải, rồi truyền chúng vào hàm hỗ trợ compute, hàm này nhận một con trỏ hàm.

Lưu ý: bạn chỉ cần viết các hàm. Các bài kiểm tra gọi trực tiếp apply_twice và kiểm tra giá trị trả về, vì vậy đừng đọc đầu vào hay in ra bất cứ thứ gì.

Cấu trúc bắt buộc:

  • Định nghĩa một typedef có tên Operation cho con trỏ hàm nhận hai tham số int và trả về một int
  • Định nghĩa hai hàm thao tác: add (trả về a + b) và multiply (trả về a * b)
  • Định nghĩa hàm compute nhận hai số nguyên và một con trỏ hàm Operation, sau đó trả về kết quả gọi thao tác đó
  • Trong apply_twice, chọn thao tác phù hợp dựa trên mã, rồi dùng compute hai lần: lần đầu với các số ban đầu, lần sau với kết quả và số thứ hai

Logic:

  1. Chọn hàm thao tác dựa trên op_code (1 = add, 2 = multiply)
  2. Gọi compute(a, b, operation) để lấy kết quả trung gian
  3. Gọi compute(intermediate, b, operation) để lấy kết quả cuối cùng
  4. Trả về kết quả cuối cùng

Tham số:

  • a (int): Số thứ nhất
  • b (int): Số thứ hai
  • op_code (int): Mã thao tác (1 để cộng, 2 để nhân)

Giá trị trả về: Kết quả sau khi áp dụng thao tác đó lần lượt hai lần (int)

Ví dụ: Với a = 5, b = 3, op_code = 1 (cộng):

  • Lần tính đầu tiên: 5 + 3 = 8
  • Lần tính thứ hai: 8 + 3 = 11
  • Trả về: 11

Với a = 2, b = 4, op_code = 2 (nhân):

  • Lần tính đầu tiên: 2 × 4 = 8
  • Lần tính thứ hai: 8 × 4 = 32
  • Trả về: 32

Tự làm thử

int apply_twice(int a, int b, int op_code) {
    // Viết code vào đây
}
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