C 语言中的回调函数
回调函数用途极其广泛,尤其是在事件驱动编程中。当特定事件触发时,映射到该事件的回调函数将响应这些事件执行。这通常用于 GUI 应用程序中,像按钮点击这样的操作可以启动一系列预定义的操作。
回调函数
回调函数基本上是任何作为参数传递给其他代码的可执行代码,这些代码预计会在给定时间回调或执行参数。我们可以这样定义它:如果将一个函数的引用传递给另一个函数进行调用,则该函数称为回调函数。
回调机制依赖于函数指针。函数指针是一个变量,用于存储函数的内存地址。
这是一个简单的 C 语言 hello() 函数 -
void hello(){ printf("Hello World."); }
我们声明一个指向此函数的指针,如下所示:-
void (*ptr)() = &hello;
现在我们可以借助此函数指针来调用该函数,(*ptr)();
C 语言回调函数示例
在此示例中,hello()函数被定义为myfunction()的参数。
#include <stdio.h> void hello(){ printf("Hello World "); } void callback(void (*ptr)()){ printf("Calling a function with its pointer "); (*ptr)(); // 调用回调函数 } main(){ void (*ptr)() = hello; callback(ptr); }
输出
Calling a function with its pointer Hello World
带参数的回调函数
在下面的示例中,我们还声明了两个具有相同原型的函数 - square() 和 root()。
int square(int val){ return val*val; } int root(int val){ return pow(val, 0.5); }
回调函数被定义为接收一个参数以及一个带有与上述函数匹配的整数参数的函数指针。
int callback(int a, int (*ptr)(int)){ int ret = (*ptr)(a); return ret; }
在 main() 函数中,我们通过传递一个整数和函数名称(square / root)来调用回调函数,该函数名称将成为回调定义中的函数指针。
带参数的回调函数示例
完整代码如下 -
#include <stdio.h> #include <math.h> int callback(int a, int (*print_callback)(int)); int square(int value); int root (int value); int main(){ int x = 4; printf("Square of x: %d is %d ", x, callback(x, square)); printf("Square root of x: %d is %d ", x, callback(x, root)); return 0; } int callback(int a, int (*ptr)(int)){ int ret = (*ptr)(a); return ret; } int square(int val){ return val*val; } int root(int val){ return pow(val, 0.5); }
输出
Square of x: 4 is 16 Square root of x: 4 is 2
C 语言中的回调类型
有两种类型的回调 -
同步回调
当回调被传递给另一个函数时,该函数会将其作为自身进程的一部分执行,这种回调是同步的。调用函数会等待回调完成后再继续执行。当您需要立即获得结果或希望确保任务完成后再继续执行时,这种回调非常有用。
异步回调
在这种情况下,调用函数会触发回调,但不会等待回调完成。相反,它会继续执行。这会产生非阻塞操作。它通常用于事件驱动编程。
通用回调函数可以帮助开发人员编写功能更强大、适应性更强的 C 程序。
在本章中,我们解释了如何使用函数指针来增强 C 程序的灵活性。此外,我们还展示了如何创建不限于特定函数指针类型的通用回调函数。