Mar*_*son 8 c pointers function-pointers
我不小心在不同的地方使用了两种不同风格的C函数指针定义,并决定编写一个最小程序来测试这些差异.
这两种风格是:
int (comp (int))
Run Code Online (Sandbox Code Playgroud)
和
int (*comp)(int)
Run Code Online (Sandbox Code Playgroud)
我编写了一个最小程序,它将这两个样式用于同一个函数指针,一个用于声明一个函数,一个用于定义相同的函数,以查看编译器对此有何看法.
宣言:
int a_or_b (int (*a_fn)(), int (b_fn()), int (*comp)(int));
Run Code Online (Sandbox Code Playgroud)
定义:
int a_or_b (int (a_fn()), int (*b_fn)(), int (comp(int)))
{
int out = a_fn ();
if (comp (out))
out = b_fn ();
return out;
}
Run Code Online (Sandbox Code Playgroud)
正如您所希望的那样,对于声明中的第一个参数,我使用了样式int (*a_fn)(),而在函数的定义中,我使用了样式int (a_fn ()).我用接下来的两个参数做了类似的事情.
我推测这些可能是不兼容的类型,这些样式可能是变量的pass-by-reference和pass-by-value赋值之间的区别,但是当我编译这个程序时,编译器默默地并愉快地编译它.没有错误,没有警告,没有.
正如我已经看到很多提倡第二种风格的教程,虽然我个人更喜欢第一种用于美学目的的风格,但我对这两种风格之间的差异感兴趣并且推荐使用.
完整代码示例:
#include <stdio.h>
int a ();
int b ();
int a_or_b (int (*a_fn)(), int (b_fn()), int (*comp)(int));
int a ()
{
return 1;
}
int b ()
{
return 2;
}
int comparison (int param)
{
return param;
}
int a_or_b (int (a_fn()), int (*b_fn)(), int (comp(int)))
{
int out = a_fn ();
if (comp (out))
out = b_fn ();
return out;
}
int main (int argc, char **argv)
{
printf ("%i\n", a_or_b (a, b, comparison));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在函数参数列表中,函数被转换为函数指针。C11 标准,ISO/IEC 9899:2011,\xc2\xa76.7.6.3函数声明符(包括原型)表示:
\n\n\n\n\n\xc2\xb68 将参数声明为“函数返回类型”应调整为“指向函数返回类型的指针”\xe2\x80\xa6
\n
因此,正如所写,参数都被视为“函数指针”。不过,最好保持自洽。
\n\n请注意,函数不能返回函数:
\n\n\n\n\n\xc2\xb61 函数声明符不得指定函数类型或数组类型的返回类型。
\n
在函数声明符(函数定义或函数声明的参数列表)之外,符号是不同的:
\n\nint (*a_fn)();\nint (b_fn());\nRun Code Online (Sandbox Code Playgroud)\n\n其中第一个声明(定义)一个名为a_fn\xe2\x80\x94 的变量,它是一个指向返回int未指定(但不是可变参数)参数列表的函数的指针。
其中第二个声明存在一个名为的函数,b_fn该函数返回int一个带有未指定(但不是可变参数)参数列表的 an (并且有一组多余的括号;它可以被写成int b_fn();并且意味着相同的事情)。