这两种风格的C函数指针定义有何不同?

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)

Jon*_*ler 4

在函数参数列表中,函数被转换为函数指针。C11 标准,ISO/IEC 9899:2011,\xc2\xa76.7.6.3函数声明符(包括原型)表示:

\n\n
\n

\xc2\xb68 将参数声明为“函数返回类型”应调整为“指向函数返回类型的指针”\xe2\x80\xa6

\n
\n\n

因此,正如所写,参数都被视为“函数指针”。不过,最好保持自洽。

\n\n

请注意,函数不能返回函数:

\n\n
\n

\xc2\xb61 函数声明符不得指定函数类型或数组类型的返回类型。

\n
\n\n

在函数声明符(函数定义或函数声明的参数列表)之外,符号是不同的:

\n\n
int (*a_fn)();\nint (b_fn());\n
Run Code Online (Sandbox Code Playgroud)\n\n

其中第一个声明(定义)一个名为a_fn\xe2\x80\x94 的变量,它是一个指向返回int未指定(但不是可变参数)参数列表的函数的指针。

\n\n

其中第二个声明存在一个名为的函数,b_fn该函数返回int一个带有未指定(但不是可变参数)参数列表的 an (并且有一组多余的括号;它可以被写成int b_fn();并且意味着相同的事情)。

\n