11

当我编译下面的代码时

#include<stdio.h>

int main()
{
  int a;
  int a = 10;
  printf("a is %d \n",a);
  return 0;
}

我收到一个错误:

test3.c: In function ‘main’:
test3.c:6:5: error: redeclaration of ‘a’ with no linkage
test3.c:5:5: note: previous declaration of ‘a’ was here

但是,如果我将变量设为全局变量,则它可以正常工作。

#include<stdio.h>

int a;
int a = 10;
int main()
{
  printf("a is %d \n",a);
  return 0;
}

为什么两次声明同一个全局变量不是错误,但对局部变量这样做是错误的?

4

3 回答 3

18

在 C 中,int a;在文件范围内进行的语句是声明和暂定定义。您可以拥有任意数量的暂定定义,只要它们彼此匹配即可。

如果定义(带有初始化器)出现在翻译单元的结尾之前,则变量将被初始化为该值。具有多个初始化值是编译器错误。

如果到达翻译单元的末尾,并且没有找到非暂定定义,则变量将被初始化为零。

以上不适用于局部变量。在这里,声明也可以作为定义,并且有多个会导致错误。

于 2014-01-22T07:04:45.927 回答
2

我能想到的另一个原因是未初始化的全局变量存储在 BSS(块结构化段)中,而初始化的全局变量存储在数据段中。

我猜测存在某种名称空间解析,当发生冲突时,数据段中的变量会覆盖块结构化段中的变量。

如果你要申报

整数 a =5 整数 a = 10

在全局范围内(都在数据段中)会出现预期的冲突。

于 2014-01-22T07:00:53.087 回答
1

C 程序中不能有两个同名的全局变量。C 可能通过暂定定义规则允许同一文件范围内的多个定义,但在任何情况下,所有定义都将引用同一个变量。

局部变量

在 C 中,多个局部变量不会“合并”为一个。

所有具有相同名称的局部变量将引用不同的 int 大小的内存。

 #include<stdio.h>

 int main()
 {
  int a;
  int a = 10;
  printf("a is %d \n",a);  
  return 0;
 }

因此,当将内存分配给同一变量的重新声明时,它会给出错误。

全局变量

在 C 中,多个全局变量被“合并”为一个。所以你确实只有一个全局变量,多次声明。这可以追溯到 C 中不需要(或者可能不存在 - 不太确定)的时候。

换句话说,所有同名的全局变量都将被转换为一个变量——所以你的

#include<stdio.h>

int a;
int a = 10;
int main()
{
printf("a is %d \n",a);
return 0;
}

将引用相同的 int 大小的内存。

于 2014-01-22T06:56:47.190 回答