C 语言 - 回调函数
回调函数
回调函数是作为参数传递给另一个函数的函数。
接收函数可以在需要时回调(运行)它。
这是使代码灵活且可重用的强大方式——您可以在不改变主要逻辑的情况下决定应该运行哪个函数。
在 C 语言中,回调函数通常使用函数指针来实现。
简单回调示例
这是一个基本示例,展示了函数如何"回调"另一个函数:
实例
将一个函数作为参数传递给另一个函数:
void sayHello() {
printf("Hello from the callback!\n");
}
void runCallback(void (*callback)()) {
printf("Before calling the callback...\n");
callback();
printf("After calling the callback.\n");
}
int main() {
runCallback(sayHello);
return 0;
}
在这个示例中:
sayHello()是一个打印消息的普通函数。runCallback()接收一个函数指针作为参数。- 当
runCallback(sayHello)运行时,它在内部调用sayHello()。
注意:"回调"一词源于一个函数"回调"了之前传递给它的另一个函数这一事实。
带参数的回调
您也可以传递带参数的函数 - 只需确保函数指针类型匹配:
实例
将带参数的函数作为回调传递:
void addNumbers(int a, int b) {
printf("The sum is: %d\n", a + b);
}
void calculate(void (*callback)(int, int), int x, int y) {
callback(x, y);
}
int main() {
calculate(addNumbers, 5, 3);
return 0;
}
在这里,calculate() 接收一个函数和两个数字,然后使用这些数字作为参数调用该函数(本例中是 addNumbers())。
多个回调
您可以使用回调,让一个函数根据您传入的函数不同而表现不同。这在排序、过滤和事件处理代码中很常见。
实例
使用不同的回调函数执行不同的操作:
void greetMorning() { printf("Good morning!\n"); }
void greetEvening() { printf("Good evening!\n"); }
void greet(void (*callback)()) {
callback();
}
int main() {
greet(greetMorning);
greet(greetEvening);
return 0;
}
根据传递的函数不同,程序产生不同的输出 - 而无需更改 greet() 本身。
实际应用示例:在 qsort() 中使用回调
许多 C 标准库函数都使用回调。例如,<stdlib.h> 中的 qsort() 函数在排序时使用回调来比较元素。
您提供比较函数,qsort() 在需要时调用它。这将排序元素:
实例
#include <stdio.h>
#include <stdlib.h>
int compare(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
int main() {
int numbers[] = { 5, 2, 9, 1, 7 };
int size = sizeof(numbers) / sizeof(numbers[0]);
qsort(numbers, size, sizeof(int), compare);
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
return 0;
}
在这里,compare() 是 qsort() 用于决定如何对数字排序的回调函数。
总结
- 回调函数是作为参数传递给另一个函数的函数。
- 它允许一个函数调用另一个函数,而无需预先知道其名称。
- 回调使代码更灵活、更可重用。
- 它们在 C 标准库(如
qsort())中使用。