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

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

1)没有联系的’y’重新声明

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

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

link1 link2

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

  #include 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); } 

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

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

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

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

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

参考文献: C99标准 。

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

 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 } }