c-使用回调的优点(在非事件驱动的程序中)



我正在研究中的回调示例:https://en.wikipedia.org/wiki/Callback_(计算机编程(

#include <stdio.h>
#include <stdlib.h>
/* The calling function takes a single callback as a parameter. */
void PrintTwoNumbers(int (*numberSource)(void)) {
int val1 = numberSource();
int val2 = numberSource();
printf("%d and %dn", val1, val2);
}
/* A possible callback */
int overNineThousand(void) {
return (rand()%1000) + 9001;
}
/* Another possible callback. */
int meaningOfLife(void) {
return 42;
}
/* Here we call PrintTwoNumbers() with three different callbacks. */
int main(void) {
PrintTwoNumbers(&rand);
PrintTwoNumbers(&overNineThousand);
PrintTwoNumbers(&meaningOfLife);
return 0;
}

我了解所有的功能。然而,我想知道除了减少一条线,这样做的好处是什么:

PrintTwoNumbers(&overNineThousand);

而不是像使用常规函数一样使用它们:

int a = overNineThousand();
PrintTwoNumbers(a);

谢谢!

这是所谓的高阶函数的一个微不足道的例子。

在这个特定的例子中,它不是很有用。你说得对,直接传递数据会更容易。

这是一种允许函数泛化的技术,如果使用得当,它对减少代码重复非常有帮助。

一个典型的例子是转换列表的map函数:

var arr = [1, 2, 3];
var newArr = arr.map(x => x + 1); // Pass a function that adds one to each element
print(newArr); // Prints [2, 3, 4]

如果没有更高阶的函数,每次转换列表时都必须编写包含map的相同循环代码。如果我想在其他地方为每个元素添加2,该怎么办?还是各乘以5?通过传递一个函数,您可以告诉它您希望它如何转换每个项,而不必担心迭代。

如评论所述,另一个例子是排序函数。它们允许您传递一个确定排序顺序的函数。如果没有这种能力,您将需要为每个不同的排序顺序和元素类型编写一个新的排序函数。


很抱歉我无法在C中回答这个问题。我理解你发布的代码中发生了什么,但我不知道C,所以我无法给出使用HOF的好示例代码。

如果问题只是计算一个元素,那么是的,回调不是很有用。

现在,如果我们认为函数可能需要以(非(确定性的方式多次调用回调,那么就需要回调。

通常,C中最常见的回调之一是qsort,其中回调是强制性的。

至少有两种情况下回调是有用的:

  • 在某些数据上重复执行任务的函数。注释中给出的例子很好:将比较函数作为回调传递到排序函数中是一个有用回调的好例子
  • 枚举函数。这是指您向库请求对象列表,并且希望对每个对象执行操作。您将向枚举函数传递一个回调。示例:EnumWindows

最新更新