关于Pointers To函数声明中的函数
#include #include 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())
工作的。 谢谢。
当你编写int fun2(int fun())
,参数int fun()
转换为int (*fun)()
,它变得完全等同于:
int fun2(int (*fun)());
当您将其声明为函数参数时,在数组的情况下会发生更多的famiiar转换。 例如,如果你这样:
int f(int a[100]);
即使在这里参数类型转换为int*
,它变为:
int f(int *a);
函数类型和数组类型分别转换为函数指针类型和指针类型的原因是因为标准不允许将函数和数组传递给函数,也不能从函数返回函数和数组。 在这两种情况下,它们都会衰减为指针版本。
C ++ 03标准在§13.1/ 3中说(在C ++ 11中也是如此),
仅与那个不同的参数声明是函数类型,而另一个是指向相同函数类型的指针是等效的 。 也就是说,调整函数类型以成为函数类型的指针(8.3.5) 。
这里有一个更有趣的讨论:
- 参考函数语法 – 有和没有&
int fun2(int (*fun)())
和int fun2(int fun())
完全相同。 当您从函数类型声明函数参数时,编译器会将其用作指向同一函数类型的指针。
这两个函数定义在C中是等价的:
int fun2(int fun()) { ... }
和
int fun2(int (*fun)()) { ... }
在第一个函数中,参数被调整为函数指针。 见C标准段落:
(C99,6.7.5.3p8)“参数声明为”函数返回类型”应调整为”函数返回类型的指针”,如6.3.2.1所述。”
在较低级别(以及基于x86的架构)中查看它:
int fun2(int fun())
int fun()的地址被推入堆栈并传递给fun2()函数。
int fun2(int (*fun)())
int fun()的指针地址被推入堆栈并传递给fun2()函数。
结果是一样的,除了第二个,你通过引用传递fun()的地址,并在第一个中通过值传递它。