在C中,为什么多个声明适用于全局变量而不适用于局部变量?

时间:2013-03-31 21:24:36

标签: c

在下面的代码中,为什么多个声明(和一个定义)适用于全局变量x,而不适用于y函数内的局部变量main()?它显示以下2个错误:

  

1)重新声明没有连接的'y'

     

2)之前的'y'声明就在这里

为什么它显示局部变量但不是全局变量的错误?不仅是我的书,而且本论坛的以下2个链接清楚地表明我们可以多次声明变量(尽管只定义一次)。

link1 link2

并且请注意解释第一个错误“没有联动”的“重新声明”是什么意思?什么联系和谁?将局部变量链接到哪里?

    #include<stdio.h>

    int x;
    int x;
    int x=303;

    int main(void)
    {

      int y;
      int y;
      int y=776;   //Works fine if above 2 declarations are removed!!

      printf("The value of x is %d,and of y is %d",x,y);

    }

3 个答案:

答案 0 :(得分:19)

在C和C ++中,函数中的int y; 既是声明又是定义。

在C中,文件范围中的int x;(在任何函数之外)是声明和暂定定义。允许多个暂定定义;只允许一个定义

答案 1 :(得分:5)

这是C99标准第6.2.2节第2部分中定义的方式:

  

在构成整个程序的翻译单元和库集中   具有外部链接的特定标识符的声明表示相同的对象或   功能。在一个翻译单元内,每个声明的内部声明   连接表示相同的对象或功能。每个声明的声明都没有   link表示一个独特的实体。

“全局”变量x具有外部链接,因此它们表示相同的对象。另一方面,本地y变量没有链接,因此存在冲突。

参考文献:C99 Standard

答案 2 :(得分:3)

对于外部变量,任何非初始化的声明都是暂定的。这些本身不会创建任何存储,因此允许多个存储。以你的榜样为例:

int x;      // tentative def
int x;      // and again -- ok
int x=303;  // definition -- ok
int x=303;  // multiple definition -- error

如果在文件末尾只有暂定定义,则变量定义一次,并设置为0.

这意味着如果您链接到另一个也具有x暂定定义的文件,则根据标准会出现错误。但是,大多数编译器/链接器总是允许这样做,并且它在标准中被定义为扩展。

对于局部变量,由于范围规则,每个声明都是一个定义。但是,这是允许的:

void func(void)
{
   int y = 0;
   {
      int y = 1;   // a completely different y
   }
}