iBu*_*Bug 3 c history function-pointers language-lawyer
说这个简单的代码:
int foo(void);
int (*p)(void);
p = foo;
p = &foo;
int a = p();
int b = (*p)();
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,第3行和第4行都有效,第5行和第6行也都有效.
事实上,如果你在使用函数指针时尝试使用类似的变量指针,你的程序肯定会死掉.那为什么它对函数指针有效呢?
的函数(更准确地说,一个功能标志)转换为一个指针指向一个功能(除非当它的操作数sizeof,_Alignof或一元&).所以,foo和&foo是相同的东西,因为foo被自动转换为&foo.
同样,p是一个指向函数的指针,函数*p也是如此,因此它会自动转换为函数的地址.
实际上,因为*p它会立即转换回指针,你可以*再次应用它,如同int b = (**p)();.你可以一次又一次地做到这一点:int b = (************p)();.
从2011 C标准(委员会草案N1570),6.3.2.1 4:
甲功能标志是具有功能类型的表达式.除非它是运算
sizeof符,_Alignof运算符或一元运算&符的操作数,否则将具有"函数返回类型 " 类型的函数指示符转换为具有"指向函数返回类型的指针"类型的表达式.
这只是因为C开发人员希望能够轻松使用类似函数foo和指向函数的函数p.如果你不得不foo()为一个人和(*p)()另一个人写作,那将会有点令人讨厌.或至少更多打字.或者,如果你必须(&foo)()为一个人而p()另一个人写作,那就再次打字了.所以他们只是在你编写函数时说,我们会自动将它作为指针,你可以不用再打字就调用它.
我想他们可以说函数调用操作符可以接受函数或指向函数的指针,但是他们选择了自动转换.
推论:如果你不知道某个东西是函数,还是指向函数的指针,或指向函数指针的指针等,只需在它前面拍一百个星号,编译器就会停止它.得到了这个功能.