抱歉,我对使用函数指针有点困惑。我键入了 3 个以不同方式使用函数指针的函数,但令人难以置信的是它们都有效。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
typedef int(*pfun)(int a, int b);
int add(int a, int b)
{
return a + b;
}
int f1()
{
pfun fun = add;
return fun(3, 4);
}
int f2()
{
pfun fun = &add; //Why did't compiler report an error?
return fun(3, 4); //Why it could work? The value in fun should be a pointer of function pointer.
}
int f3()
{
pfun fun = &add;
return (*fun)(3, 4); //Why did't compiler report an error?
}
int main()
{
printf("%d,%d,%dn", f1(),f2(),f3());
system("pause");
return 0;
}
输出为 7,7,7,VS2017 中没有编译错误。
f2
你的评论是错误的。&add
不可能是指针到指针;它将指向哪个指针对象?类似地,给定char array[N];
,&array
不是指针到指针。它具有指针到数组类型。在大多数情况下,函数和数组类型标识符的计算结果都是指针(分别是指向函数或指向第一个元素的指针(,但这并不意味着它们本身具有指针类型。
在f3
中,*fun
是一个计算函数的表达式,它总是隐式转换为指向函数的指针。根本没有函数类型的表达式这样的东西。因此,****************fun
的计算结果也与fun
(指向add
的指针(相同。
请注意,函数调用运算符()
将具有指向函数类型的表达式作为其操作数。每当通过其标识符调用函数时,您都在使用函数指针。
根据语言,这些形式都不比其他任何形式更"正确",但我认为大多数 C 程序员发现使用&
和*
运算符充其量是多余的(如果不是误导的话(函数,并且会认为f1
最好的。
add
和&add
之间没有区别。这两个表达式都表示函数的地址。
至于
fun(3, 4);
// vs.
(*fun)(3, 4);
函数指针是隐式取消引用还是显式取消引用并不重要。