标识符列表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);
。 虽然我们通常不喜欢这样做,因为缺乏可读性。