考虑此代码具有 3 个不同的函数调用语义:
void f(void){
puts("OK");
}
int main(void){
f();
(*f)();
(&f)();
return 0;
}
第一种是调用 f 的标准方式,
第二个是取消引用函数指针的语义,
但在第三个中,我将 & 运算符应用于函数名称,它似乎工作正常。
第二种和第三种情况会发生什么?
谢谢。
函数调用总是通过函数指针执行的。从 C99 第 6.5.2.2 节:
表示被调用函数的表达式应具有指向函数的类型指针。
但是,几乎在所有情况下,函数类型都会衰减为函数指针类型。从 C99 第 6.3.2.1 节:
除非它是运算
sizeof
符或一元&
运算符的操作数,否则类型为“函数返回类型”的函数指示符将转换为类型为“指向函数返回类型的指针”的表达式。
因此,您的三个电话被评估为:
(&f)();
(&(*(&f)))();
(&f)();
都是有效的。但很明显,第一个 ( f()
) 是最干净、最容易阅读的。
在第二种情况下,您使用的是函数指针。函数指针用于记住对函数的引用,并能够在调用的其他地方调用它。它们通常用于实现回调。因此,如果您存储了指向函数的指针,则应使用第一种表示法。
我认为第一个和第三个是等价的。事实上,如果您声明一个函数指针,您可以通过以下两种方式对其进行初始化:
void AFunction();
void (*funcPtr)() = NULL;
funcPtr = AFunction;
funcPtr = &AFunction;