我正在研究以下回调示例: https://en.wikipedia.org/wiki/Callback_(computer_programming)
#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 %d\n", 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);
谢谢!
答案 0 :(得分:2)
这是所谓的Higher Order Function的简单例子。
在此特定示例中,它不是很有用。您说对了,直接传递数据会更容易。
这是一种允许对函数进行泛化的技术,并且在正确使用时对减少代码重复非常有帮助。
一个典型的示例是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的良好示例代码。
答案 1 :(得分:0)
如果问题只是计算一个元素,那么是的,回调不是很有用。
现在,如果我们认为函数可能需要以(非确定性的)方式多次调用回调,那么就需要回调。
通常,C语言中最常见的回调之一是qsort
,其中回调是必需的。
答案 2 :(得分:0)
至少有两种情况下回调是有用的:
EnumWindows
。