#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())
是如何运作的。谢谢。
答案 0 :(得分:33)
当您编写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)。
这里有一个更有趣的讨论:
答案 1 :(得分:6)
int fun2(int (*fun)())
和int fun2(int fun())
完全相同。当您从函数类型声明函数参数时,编译器会将其用作指向同一函数类型的指针。
答案 2 :(得分:3)
这两个函数定义在C:
中是等效的 int fun2(int fun()) { ... }
和
int fun2(int (*fun)()) { ... }
在第一个函数中,参数被调整为函数指针。见C标准段落:
(C99,6.7.5.3p8)“参数声明为''函数返回类型''应调整为''指向函数返回类型''的指针,如6.3.2.1所述。”
答案 3 :(得分:-3)
在较低级别(以及基于x86的架构)中查看它:
int fun2(int fun())
int fun()的地址被压入堆栈并传递给fun2()函数。
int fun2(int (*fun)())
int fun()的指针地址被推入堆栈并传递给fun2()函数。
结果是一样的,除了第二个,你通过引用传递fun()的地址,并在第一个地方通过值传递它。