标识符列表Vs中的参数类型列表

6.7.6.3 Function declarators (including prototypes) 

标准的这一部分涉及'Identifier list''Parameter type list'

首先,函数声明(非定义)与函数原型相同。 我对么? 如果这是对的,那么为什么标准会说'including prototypes'

我无法理解'Identifier list''Parameter type list'在function声明方面的区别。

 int fun(); // Declaration int fun(int x)// Definition, but the signature doesn't match and it works. { return x; } 

有人可以解释一下,我很困惑?

函数声明与函数原型不同。 原型是一种特殊的声明。 例如,这是一个不是原型的函数声明

 int foo(); 

以下声明是原型

 int foo(int a, double b); int bar(char, float); float baz(void); 

即原型是一个声明,描述函数参数的数量和类型。 非原型声明没有说明参数。

现在,除了“现代”函数定义之外,C语言仍然支持旧的K&R风格的函数定义。 K&R风格的function定义如下所示

 int foo(a, b) int a; double b; { ... } 

“现代”函数定义如下所示

 int foo(int a, double b) { ... } 

如您所见,K&R风格的参数列表只是a, b 。 它包含参数名称,但不包括其类型。 这就是语法所指的标识符列表 。 “modern”参数列表是int a, double b ,这是语法引用的参数类型列表

标识符列表是K&R样式函数定义语法的一部分,而参数类型列表是“现代”函数定义语法的一部分。

另请注意,在C语言中声明

 int foo(); 

并不意味着foo不参数。 这意味着foo接受一个未指定数量的参数,即它只是在调用时关闭foo参数类型检查,参数号检查和参数转换。 这种“签名”将匹配foo的定义与任何参数列表。 这个

 int foo(int x) { ... } 

对于如上所示声明的foo是一个完全有效的定义。 它用()声明的事实只是意味着编译器不会在调用点validation参数。 您有责任确保使用int类型的一个参数调用foo

在C11标准

6.7.6.3函数声明符(包括原型)
约束

 D( parameter-type-list ) or D( identifier-listopt ) 

在声明function时,您无需提供标识符列表。 你应该至少提一下类型列表

例:

 int sum(int,int); //declaration int sum(int a,int b); //declaration 

两者都是相同function的声明。

但第二个你也提到了可选的标识符。

C11(ISO / IEC 9899:201x)§6.2.1 标识符的范围第2节

函数原型是声明其参数类型的函数的声明。

在您的示例中,对于函数定义

 int fun(int x) { return x; } 

两个int func(int x);int func(); 是有效的函数声明。 但只有前者才是function原型。

你甚至可以在函数声明中省略变量名,例如int func(int); 。 虽然我们通常不喜欢这样做,因为缺乏可读性。