【问题标题】:About Pointers To Functions in function declarations关于函数声明中指向函数的指针
【发布时间】:2012-03-08 19:24:43
【问题描述】:
#include<stdio.h>
#include<stdlib.h>

int fun1()
{
    printf("I am fun1.");
    return 0;
}

int fun2(int fun())
{
    fun();
    return 0;
}

int main()
{
    fun2(fun1);
    return 0;
}

上面的程序可以运行。就我而言,我可以理解int fun2(int (*fun)()),但我不知道int fun2(int fun()) 是如何工作的。谢谢。

【问题讨论】:

  • 这在 C、C99 Strict、C++03 和 C++11 中有效。我很惊讶。

标签: c++ c function pointers function-pointers


【解决方案1】:

当你写int fun2(int fun())时,参数int fun()转换成int (*fun)(),就完全等价于这个了:

int fun2(int (*fun)());

当您将数组声明为函数参数时,会发生更熟悉的转换。例如,如果你有这个:

int f(int a[100]);

即使在这里参数类型转换为int*,它变成这样:

int f(int *a);

之所以将函数类型和数组类型分别转换为函数指针类型和指针类型,是因为标准不允许将函数和数组传递给函数,也不能您从函数返回函数和数组。在这两种情况下,它们都会衰减到它们的指针版本。

C++03 标准在 §13.1/3 中说(在 C++11 中也是如此),

仅在一个是函数类型而另一个是指向相同函数类型的指针的参数声明是等效即函数类型调整为指向函数类型的指针(8.3.5)

还有一个更有趣的讨论在这里:

【讨论】:

    【解决方案2】:

    int fun2(int (*fun)())int fun2(int fun()) 完全相同。当您从函数类型声明函数参数时,编译器会使用它,就好像它是指向同一函数类型的指针一样。

    【讨论】:

      【解决方案3】:

      这两个函数定义在 C 中是等价的:

       int fun2(int fun()) { ... }
      

       int fun2(int (*fun)()) { ... }
      

      在第一个函数中,参数被调整为函数指针。参见 C 标准段落:

      (C99, 6.7.5.3p8) “将参数声明为‘函数返回类型’应调整为‘指向函数返回类型的指针’,如 6.3.2.1。”

      【讨论】:

        【解决方案4】:

        在较低级别(以及基于 x86 的架构中)查看它:

        int fun2(int fun())
        

        int fun() 的地址被压入堆栈并传递给 fun2() 函数。

        int fun2(int (*fun)())
        

        int fun()pointer 地址被压入堆栈并传递给 fun2() 函数。

        结果是一样的,除了第二个,你通过引用传递 fun() 的地址,而在第一个你通过值传递它。

        【讨论】:

        • 函数地址和函数指针地址有什么区别?或者,你所说的“指针地址”是什么意思?
        • 指针地址是指**p。也就是指向函数地址的指针的地址。
        • 你说的 **p 是什么意思?这看起来像可以被取消引用两次被取消引用两次的东西?指向函数的指针的地址类似于:int(*fnptr)(); int (**p)() = &amp;fnptr; 但问题中没有出现类似的内容?
        • 忘掉**p。我的意思是指向函数地址的指针的地址。另外,为什么我的回答被否决而没有任何解释?
        • @m0skit0:解释在这个讨论中。答案很混乱。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多