对不起,但是我对使用函数指针有些困惑。我输入了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,%d\n", f1(),f2(),f3());
system("pause");
return 0;
}
输出为7,7,7,在VS2017中没有编译错误。
答案 0 :(得分:2)
在f2
中,您的评论是错误的。 &add
不可能是指针到指针;它指向什么指针对象?同样,在给定char array[N];
的情况下,&array
不是指针对指针。它具有数组指针类型。在大多数情况下,函数和数组类型标识符都对指针(分别是指向函数的指针或指向第一个元素的指针)求值,但这并不意味着它们本身具有指针类型。
在f3
中,*fun
是对函数求值的表达式,该表达式始终隐式转换为指向函数的指针。根本就没有函数类型的表达式。因此,****************fun
的计算结果与fun
相同(指向add
的指针)。
请注意,函数调用运算符()
将具有指针指向函数类型的表达式作为其操作数。每当您通过其标识符调用函数时,就使用函数指针。
每种语言的任何一种形式都比其他任何一种都“正确”,但是我认为大多数C程序员发现使用&
和*
运算符充其量是多余的(如果没有引起误解)功能,并认为f1
是最好的。
答案 1 :(得分:1)
add
和&add
之间没有区别。这两个表达式都代表该函数的地址。
至于
fun(3, 4);
// vs.
(*fun)(3, 4);
函数指针是隐式解引用还是显式引用都无所谓。