【问题标题】:Identifier list Vs Parameter type list in CC中的标识符列表与参数类型列表
【发布时间】:2013-09-16 05:12:04
【问题描述】:
6.7.6.3 Function declarators (including prototypes)

这部分标准处理'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; }

谁能解释一下,我很困惑?

【问题讨论】:

标签: c function


【解决方案1】:

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

int foo();

以下声明是原型

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

即原型是描述函数参数的数量和类型的声明。非原型声明不涉及参数。

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

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

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

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

如您所见,K&R 风格的参数列表就是a, b。它包括参数名称,但不包括它们的类型。这就是语法所指的标识符列表。 “现代”参数列表是int a, double b,这就是语法所指的parameter-type-list

identifier-list 是 K&R 风格的函数定义语法的一部分,而 parameter-type-list 是“现代”函数定义语法的一部分。

还要注意在 C 语言中的声明

int foo();

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

int foo(int x)
{
  ...
}

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

【讨论】:

  • 值得注意的是:foo() 声明阻止了 floatchar 参数,例如 foo(float): stackoverflow.com/questions/5481579/…
  • 为什么复合类型在这种情况下不适用,我的意思是在不指定参数的声明和函数foo的定义之间,所以编译器可以推断出函数的原型并使用它在翻译单元中调用时检查参数编号和类型,其中只给出没有原型的声明?
【解决方案2】:

在 C11 标准中

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

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

在声明函数时,您不需要提供标识符列表。但是你至少应该提到类型列表

示例:

int sum(int,int); //declaration  

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

两者都是同一个函数的声明。

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

【讨论】:

    【解决方案3】:

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

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

    以您的示例为例,对于函数定义

    int fun(int x)
    { return x; }
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-28
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 2013-06-05
      • 2019-02-01
      相关资源
      最近更新 更多