指向函数形参的指针vs函数形参



我想了解f1f2这两个声明之间的区别是什么,下面:在f1中,我将参数声明为指向void()类型函数的指针,f2声明与f1有何不同?声明是否相等?在main中,我可以用原型void ()的函数调用它们。我理解通过值/指针/引用传递的概念,但这些都是函数,并没有真正理解的区别。这不像我可以"修改"在f1中作为参数传递的函数…谢谢!

PS:在遇到众所周知的最令人烦恼的解析问题时遇到了这个问题:)

#include <iostream>
using namespace std;
void f1(void (*x)())
{
    x();
}
void f2(void x())
{
    x();
}
void g1()
{
    cout << "Invoking f1(g1())" << endl;
}
void g2()
{
    cout << "Invoking f2(g2())" << endl;
}

int main() 
{
    f1(g1);
    f2(g2);
}

程序编译后输出为

Invoking f1(g1())
Invoking f2(g2())

在C和c++中,如果将函数形参声明为函数类型,则其类型将被调整为函数指针。

C99,§6.7.5.3/8

将形参声明为"函数返回类型"应调整为"指向的指针"函数返回类型",如6.3.2.1.

c++ 11日§8.3.5/5

…后确定每个参数的类型,任何类型为"T的数组"或"返回T的函数"的参数都是分别调整为"指向T的指针"或"指向返回T的函数的指针"…

因此,在c++中,例如,我们可以将f1f2的类型都写为void(void(*)())

它们是等价的。你可能会对参数的隐式指针转换感到困惑。

由于不能将函数作为参数传递给函数(在C语言中,除了调用函数或获取函数的地址外,不能对函数做任何操作),编译器会悄悄地将参数更改为指向函数的指针。

这与数组的情况非常相似——你也不能将数组作为函数参数传递,所以每当你将函数参数声明为数组时,它就会无声地变成一个指针。

它们是完全相同的东西的可选语法。在这两种情况下都传递函数指针,但允许在参数列表中使用非指针语法。函数名的使用总是衰减为指向函数的指针(这可能递归地发生)。

最新更新