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

Sta*_*kIT 6 c function

6.7.6.3 Function declarators (including prototypes)
Run Code Online (Sandbox Code Playgroud)

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

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

我无法理解函数声明'Identifier list''Parameter type list'函数声明之间的区别.

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

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

AnT*_*AnT 12

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

int foo();
Run Code Online (Sandbox Code Playgroud)

以下声明是原型

int foo(int a, double b);
int bar(char, float);
float baz(void);
Run Code Online (Sandbox Code Playgroud)

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

现在,除了"现代"函数定义之外,C语言仍然支持旧的K&R风格的函数定义.K&R风格的功能定义如下所示

int foo(a, b)
int a;
double b;
{
  ...
}
Run Code Online (Sandbox Code Playgroud)

"现代"函数定义如下所示

int foo(int a, double b)
{
  ...
}
Run Code Online (Sandbox Code Playgroud)

如您所见,K&R风格的参数列表就是a, b.它包含参数名称,但不包括其类型.这就是语法所指的标识符列表."现代"参数列表是int a, double b,这就是语法所指的参数类型列表.

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

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

int foo();
Run Code Online (Sandbox Code Playgroud)

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

int foo(int x)
{
  ...
}
Run Code Online (Sandbox Code Playgroud)

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