Hàm Callback trong C

Xin chào, những người đam mê lập trình! Hôm nay, chúng ta sẽ cùng khám phá thế giới kỳ diệu của hàm callback trong C. Là người giáo viên khoa học máy tính gần gũi của bạn, tôi rất vui mừng được hướng dẫn bạn qua khái niệm này. Tin tôi đi, một khi bạn nắm vững callback, bạn sẽ cảm thấy như mình đã解锁 một siêu năng lực mới trong lập trình!

C - Callback Function

Hàm Callback là gì?

Hãy bắt đầu từ cơ bản. Hãy tưởng tượng bạn đang tham gia một buổi tiệc pizza (vì ai lại không yêu thích pizza?), và bạn nhờ bạn của mình gọi bạn khi pizza đến. Bạn của bạn thực chất đang thực hiện một callback - họ gọi bạn lại khi một sự kiện cụ thể xảy ra.

Trong lập trình C, hàm callback hoạt động tương tự. Đó là một hàm mà chúng ta truyền vào một hàm khác. Hàm này sau đó "gọi lại" (thực thi) hàm truyền vào khi một sự kiện cụ thể xảy ra hoặc một nhiệm vụ được hoàn thành.

Dưới đây là cấu trúc đơn giản của một hàm callback:

void callback_function() {
// Thân hàm
}

void main_function(void (*callback)()) {
// Một số mã
callback();  // Gọi hàm callback
// Nhiều mã hơn
}

int main() {
main_function(callback_function);
return 0;
}

Trong ví dụ này, callback_function là hàm callback của chúng ta. Chúng ta truyền nó vào main_function, sau đó main_function gọi nó tại một điểm nào đó trong quá trình thực thi của mình.

Ví dụ về Hàm Callback trong C

Hãy xem một ví dụ cụ thể hơn. Chúng ta sẽ tạo một chương trình đơn giản sử dụng callback để in một thông báo sau khi một phép toán được thực hiện.

#include <stdio.h>

// Hàm callback của chúng ta
void print_result(int result) {
printf("Kết quả là: %d\n", result);
}

// Hàm thực hiện phép toán và gọi callback
void perform_operation(int a, int b, void (*callback)(int)) {
int sum = a + b;
callback(sum);  // Gọi hàm callback với kết quả
}

int main() {
perform_operation(5, 3, print_result);
return 0;
}

Trong ví dụ này:

  1. Chúng ta định nghĩa một hàm callback print_result nhận một số nguyên và in nó.
  2. Hàm perform_operation nhận hai số nguyên và một con trỏ hàm.
  3. Trong perform_operation, chúng ta tính tổng và sau đó gọi hàm callback với tổng này.
  4. Trong main, chúng ta gọi perform_operation với các số của chúng ta và hàm callback print_result.

Khi bạn chạy chương trình này, nó sẽ вывод: "Kết quả là: 8"

Hàm Callback với Các Tham số

Callbacks cũng có thể nhận nhiều tham số. Hãy mở rộng ví dụ trước để bao gồm nhiều phép toán hơn:

#include <stdio.h>

// Hàm callback với nhiều tham số
void print_operation(char operation, int a, int b, int result) {
printf("%d %c %d = %d\n", a, operation, b, result);
}

// Hàm thực hiện phép toán và gọi callback
void perform_operation(int a, int b, char op, void (*callback)(char, int, int, int)) {
int result;
switch(op) {
case '+': result = a + b; break;
case '-': result = a - b; break;
case '*': result = a * b; break;
case '/': result = a / b; break;
default: printf("Phép toán không hợp lệ\n"); return;
}
callback(op, a, b, result);
}

int main() {
perform_operation(5, 3, '+', print_operation);
perform_operation(10, 4, '-', print_operation);
perform_operation(7, 2, '*', print_operation);
perform_operation(20, 5, '/', print_operation);
return 0;
}

Chương trình này sẽ вывод:

5 + 3 = 8
10 - 4 = 6
7 * 2 = 14
20 / 5 = 4

Ở đây, hàm callback print_operation nhận bốn tham số: phép toán, hai vế, và kết quả. Điều này cho phép chúng ta tạo ra một đầu ra linh hoạt và thông tin hơn.

Loại Callback trong C

Trong C, chúng ta có thể phân loại callbacks thành hai loại chính:

  1. Callbacks Đồng bộ: Những callback này được thực thi ngay lập tức bởi hàm mà chúng được truyền vào. Các ví dụ của chúng ta ở trên là callbacks đồng bộ.

  2. Callbacks Không Đồng bộ: Những callback này được lên lịch để thực thi sau, thường được sử dụng trong lập trình sự kiện hoặc khi xử lý các thao tác I/O.

Hãy xem bảng tóm tắt các loại này:

Loại Mô tả Trường hợp sử dụng Ví dụ
Đồng bộ Thực thi ngay lập tức Các thao tác đơn giản, phép toán Ví dụ về các phép toán của chúng ta
Không Đồng bộ Thực thi sau Xử lý sự kiện, các thao tác I/O Callbacks cho việc đọc/ghi tệp, các bộ xử lý sự kiện GUI

Dưới đây là một ví dụ đơn giản về callback không đồng bộ sử dụng các tín hiệu trong C:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void callback_function(int signum) {
printf("Nhận được tín hiệu %d\n", signum);
}

int main() {
signal(SIGALRM, callback_function);
alarm(5);  // Đặt báo động sau 5 giây

printf("Đang chờ báo động...\n");
pause();  // Chờ một tín hiệu

return 0;
}

Trong ví dụ này, callback_function được thiết lập như một callback không đồng bộ mà sẽ được gọi khi tín hiệu SIGALRM được nhận. Hàm alarm(5) đặt một计时器 5 giây, sau đó tín hiệu SIGALRM sẽ được gửi, kích hoạt callback của chúng ta.

Và thế là xong, các bạn! Chúng ta đã cùng nhau hành trình qua thế giới của các hàm callback trong C. Nhớ rằng, callbacks là những người bạn trung thành trong các cuộc phiêu lưu lập trình của bạn - họ luôn sẵn sàng hành động khi bạn cần. Hãy tiếp tục thực hành, và sớm bạn sẽ sử dụng callbacks như một chuyên gia!

Credits: Image by storyset