函数类型与函数指针类型

use*_*270 9 c++

我试图理解以下两个代码块之间的区别:

void f(int (*func)(int))
{
    func(5);
}
Run Code Online (Sandbox Code Playgroud)

void g(int (func)(int))
{
    func(5);
}
Run Code Online (Sandbox Code Playgroud)

在给定以下代码的情况下,两个函数的工作方式相同:

int blah(int a)
{
    cout << "hello" << endl;
    return 0;
}

int main()
{
    f(blah);
    g(blah);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我写下面的代码:

int (*foo)(int);
int (goo)(int);
foo = blah;
goo = blah;
Run Code Online (Sandbox Code Playgroud)

我得到goo = blah的编译错误.但是在第一个例子中,我可以调用make函数调用g(blah),它看起来与goo = blah非常相似.为什么一个工作而另一个工作?

Mik*_*our 9

有点令人困惑的是,您可以声明一个函数将函数作为参数(即使这没有意义),效果是使参数成为函数指针.这类似于声明一个看起来像数组的函数参数的方式,但实际上是一个指针.

函数参数可以是函数的名称,有或没有&显式获取其地址.如果省略&,则有一个隐式的函数到指针转换.同样,这类似于传递(指向)数组,其中隐式数组到指针转换意味着您只需要编写数组的名称,而不是&array[0].

在声明变量时,该规则不适用; int goo(int);(有或没有不必要的括号goo)声明一个函数,而不是一个指针,你不能分配给函数.

  • @Deduplicator:不,因为那是不正确的.由于隐式转换,有时不需要它们.(遗憾的是,如果不破坏30多年的遗留代码,禁止隐含转换不是一种选择). (2认同)

Bar*_*mar 5

它类似于数组和指针之间的区别,例如,如果您有:

char *foo;
char bar[N];
Run Code Online (Sandbox Code Playgroud)

你可以做:

foo = bar;
Run Code Online (Sandbox Code Playgroud)

但你不能这样做:

bar = foo;
Run Code Online (Sandbox Code Playgroud)

当函数类型用于参数声明时,它会被转换为等效的函数指针,就像声明一样:

void fun(int arr[]);
Run Code Online (Sandbox Code Playgroud)

翻译为:

void fun(int *arr);
Run Code Online (Sandbox Code Playgroud)