这两种风格的 C 函数指针定义是否不同?
Are these two styles of C function pointer definition different?
我发现自己不小心在不同的地方使用了两种不同风格的 C 函数指针定义,因此决定编写一个最小的程序来测试这些差异。
有问题的两种样式是:
int (comp (int))
和
int (*comp)(int)
我写了一个最小的程序,对同一个函数指针使用了这两种样式,一个用于函数的 声明,一个用于定义 相同的函数,看看编译器会怎么说。
声明:
int a_or_b (int (*a_fn)(), int (b_fn()), int (*comp)(int));
定义:
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 (*a_fn)()
样式,而在函数定义中,我使用了 int (a_fn ())
样式。我对接下来的两个参数做了类似的事情。
我推测这些可能是不兼容的类型,这些样式可能是变量的按引用传递和按值传递赋值之间的区别,但是当我编译这个程序时编译器默默地愉快地编译它。没有错误,没有警告,什么都没有。
因为我看过很多提倡第二种风格的教程,而我个人更喜欢第一种风格,出于审美目的,我很想知道这两种风格之间的区别是什么,推荐哪种。
完整代码示例:
#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;
}
int (comp (int))
和int (*comp)(int)
作为函数参数时是等价的。函数指示符被转换为指向函数本身的指针。
C11-§6.3.2.1:
A function designator is an expression that has function type. Except when it is the operand of the sizeof
operator, the _Alignof
operator,65) or the unary &
operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".
在函数参数列表中,函数被转换为函数指针。 C11 标准,ISO/IEC 9899:2011,§6.7.6.3 函数声明符(包括原型) 说:
¶8 A declaration of a parameter as "function returning type" shall be adjusted to "pointer to function returning type"…
所以,如上所写,参数都被视为'pointer to function'。不过,最好是自洽。
注意一个函数不能return一个函数:
¶1 A function declarator shall not specify a return type that is a function type or an array type.
在函数声明符(函数定义或函数声明的参数列表)之外,符号不同:
int (*a_fn)();
int (b_fn());
其中第一个声明(定义)一个名为 a_fn
的变量 — 一个指向函数 returning int
的指针,带有未指定(但不是可变参数)参数列表。
其中第二个声明了一个名为 b_fn
的函数的存在,该函数 return 是一个 int
具有未指定(但不是可变参数)参数列表(并且有一个多余的集合括号;可以写成int b_fn();
,意思是一样的)。
我发现自己不小心在不同的地方使用了两种不同风格的 C 函数指针定义,因此决定编写一个最小的程序来测试这些差异。
有问题的两种样式是:
int (comp (int))
和
int (*comp)(int)
我写了一个最小的程序,对同一个函数指针使用了这两种样式,一个用于函数的 声明,一个用于定义 相同的函数,看看编译器会怎么说。
声明:
int a_or_b (int (*a_fn)(), int (b_fn()), int (*comp)(int));
定义:
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 (*a_fn)()
样式,而在函数定义中,我使用了 int (a_fn ())
样式。我对接下来的两个参数做了类似的事情。
我推测这些可能是不兼容的类型,这些样式可能是变量的按引用传递和按值传递赋值之间的区别,但是当我编译这个程序时编译器默默地愉快地编译它。没有错误,没有警告,什么都没有。
因为我看过很多提倡第二种风格的教程,而我个人更喜欢第一种风格,出于审美目的,我很想知道这两种风格之间的区别是什么,推荐哪种。
完整代码示例:
#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;
}
int (comp (int))
和int (*comp)(int)
作为函数参数时是等价的。函数指示符被转换为指向函数本身的指针。
C11-§6.3.2.1:
A function designator is an expression that has function type. Except when it is the operand of the
sizeof
operator, the_Alignof
operator,65) or the unary&
operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".
在函数参数列表中,函数被转换为函数指针。 C11 标准,ISO/IEC 9899:2011,§6.7.6.3 函数声明符(包括原型) 说:
¶8 A declaration of a parameter as "function returning type" shall be adjusted to "pointer to function returning type"…
所以,如上所写,参数都被视为'pointer to function'。不过,最好是自洽。
注意一个函数不能return一个函数:
¶1 A function declarator shall not specify a return type that is a function type or an array type.
在函数声明符(函数定义或函数声明的参数列表)之外,符号不同:
int (*a_fn)();
int (b_fn());
其中第一个声明(定义)一个名为 a_fn
的变量 — 一个指向函数 returning int
的指针,带有未指定(但不是可变参数)参数列表。
其中第二个声明了一个名为 b_fn
的函数的存在,该函数 return 是一个 int
具有未指定(但不是可变参数)参数列表(并且有一个多余的集合括号;可以写成int b_fn();
,意思是一样的)。