C 函数参考参数:指针与原型样式?

C 函数参考参数:指针与原型样式?,c,parameters,reference,prototype,C,Parameters,Reference,Prototype,你可以声明一个函数引用参数,比如 int g ( int (*f)(int,int) ) { 或 在我有限的C语言经验中,我从未见过原型方法。函数名f是指向函数f的指针。编译器对它们一视同仁。您可以在提问时交替使用这两种形式 但是,为了完整性起见,请参见乔纳森·莱夫勒最完整的回答中正确指出的sizeof运算符、Alignof运算符和一元数&的例外情况 你的两份声明都说: g是一个返回int的函数,它的参数是一个指向函数f的指针,f返回int的参数和int,int.我想这是一种风格,但函数的显式

你可以声明一个函数引用参数,比如

int g ( int (*f)(int,int) ) {


在我有限的C语言经验中,我从未见过原型方法。

函数名
f
是指向函数
f
的指针。编译器对它们一视同仁。您可以在提问时交替使用这两种形式

但是,为了完整性起见,请参见乔纳森·莱夫勒最完整的回答中正确指出的
sizeof
运算符、
Alignof
运算符和
一元数&
的例外情况

你的两份声明都说:
g是一个返回int的函数,它的参数是一个指向函数f的指针,f返回int的参数和int,int.

我想这是一种风格,但函数的显式指针表示法符合古代的惯例,也符合编译器解释代码的方式

C11标准规定:

8参数声明为“函数返回类型”应调整为“指向函数返回类型的指针”,如6.3.2.1所示

并说:

^4函数指示符是具有函数类型的表达式。除非是
sizeof
运算符、
\u Alignof
运算符(65)或一元
&
运算符的操作数,否则类型为“函数返回类型”的函数指示符将转换为类型为“指向函数返回类型的指针”的表达式

65)由于未进行此转换,因此
sizeof
\u Alignof
运算符的操作数仍然是函数指示符,并且违反了6.5.3.4中的约束

因此,使用指针表示法可以明确显示编译器将执行的操作。(我仍然通常使用
(*function_ptr)(arg1,…,argN)
符号调用指向函数的显式指针,即使
function_ptr(arg1,…,argN)
也可以工作。)



*
C18标准是最新的,但目前还没有一个方便的在线HTML版本。在大多数情况下,这两者非常相似。恰巧,§6.3.2.1¨4是一个有区别的段落-C18版本没有提到
\u Alignof

作为参考,C11规范
qsort()
使用
void qsort(void*base,size\u t nmemb,size\u t size,int(*compara)(const void*,const void*))。更靠近
int(*f)(int,int)
。有趣的是,
qsort_s()
使用命名参数
…,int(*compare)(const void*x,const void*y,void*context),…
。如果我们谈论的是“古老的实践”,我的K&R参考手册(1978)第14.2段指出“如果函数名称出现在表达式中……将生成指向函数的指针”:-“标准”现在是C 2018,不是C11,我怀疑您引用的文本被修改了,因为
\u Alignof
在语法上不能应用于函数标识符。@EricPostChil:是的,但链接是指向C11标准的。我无法为C18标准的荒谬价格辩护——也许我应该发起一场GoFundMe运动?我引用的是我确定的标准。当有C18的在线版本时,我将改为链接到该版本。@JonathanLeffler:更新为当前的标准和草案,包括一个指向C 2018草案的链接,该链接表明,实际上,该文本已更改。我同情学生和业余爱好者的成本问题。我还支持使用标准的适当版本,或者对适合的问题使用非标准行为,这与当前流行的堆栈溢出相反。然而,对C标记的描述倾向于使用最新的标准,社区也是如此……对于那些使用庞大的现有C99+POSIX.1代码库的人来说,C18似乎适得其反。似乎C标准正朝着一个奇怪的方向推进,好像一些从事标准工作的人希望C包括POSIX.1的一些,但不是所有必要的部分,以实现实际功能。与我交谈过的非WindowsC程序员似乎都不喜欢跳C18;大多数人似乎和我一样,使用C99加上POSIX.1加上C11的一小部分。很遗憾,你的std开发人员没有听从开发人员社区的意见。这不完全是真的。函数标识符的类型为“函数返回void”或“函数返回”,而不是指向其中一个类型的指针。但在潮湿的上下文中,这样的标识符被转换为函数指针。这在许多方面类似于数组,包括可以看到差异的地方之一是
sizeof
操作符。将
sizeof
应用于函数类型的表达式是违反约束的,但您可以将其自由应用于函数指针。
int g ( int f(int,int) ) {