我有以下C代码:
#include <stdio.h>
int max(int x, int y, int (*compare)(int, int))
{
return (*compare)(x,y) ? x : y;
}
int greater_than(int x, int y)
{
if(x > y) return 1;
else return 0;
}
int main(void) {
printf("%d",max(6,7,greater_than));
}
它只是测试函数指针。但即使我不使用int (*compare)(int,int)
但int compare(int,int)
,代码仍然可以正常工作。如果我不取消引用函数指针或使用int compare(int,int)
但仍然取消引用它也有效。如果我通过greater_than
或&greater_than
,它也没有什么区别。为什么是这样?
关于诺瓦
这两个版本是等效的:
int max(int x, int y, int (*compare)(int, int))
int max(int x, int y, int compare(int, int))
就像数组作为参数传递给函数“衰变”成指向第一个元素的指针一样,类似的“衰变”发生在函数中。它们会衰减成函数指针。标准说
参数声明为''函数返回类型''应调整为''指向函数返回类型的指针''
所以上面的第二个(模糊的)版本被编译器静默地翻译成第一个版本。但是没有理由在参数列表中声明一个函数,所以整个问题都很奇特。
至于为什么compare(x,y)
像(*compare)(x,y)
或(*****compare)(x,y)
一样精细,这是因为每当你使用函数名或函数指针时,你总是得到一个函数指针。如果您尝试取消引用函数指针,则可以获得该函数。它再次隐式反弹回函数指针。
见Why do function pointer definitions work with any number of ampersands '&' or asterisks '*'?
初学者和退伍军人都可以安全地忘记上面那些模糊不清的规则,并且这样做:
int max(int x, int y, int (*compare)(int, int))
{
return compare(x,y) ? x : y;
}
或者更好的是,使用typedef:
typedef int compare_t (int, int);
...
int max(int x, int y, compare_t* compare)
{
return compare(x,y) ? x : y;
}
以前Lundin给出了很好的答案。 Rep太低而无法发表评论,因此我将此作为额外内容。我在stackoverflow上看到类似帖子上的链接,我喜欢这个教程。
链接到教程的起源是这个问题:How do you pass a function as a parameter in C?
上面提到的函数指针教程:http://www.newty.de/fpt/index.html
希望我不是放肆,我喜欢它,也许它会为你带来愉快的阅读。