全局变量与局部变量的重新声明

问题描述 投票:10回答:3

当我编译下面的代码时

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

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

c declaration definition redefinition one-definition-rule
3个回答
16
投票

在C中,在文件范围内生成的语句int a;是一个声明和一个暂定的定义。您可以根据需要拥有尽可能多的暂定定义,只要它们彼此匹配即可。

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

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

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


1
投票

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

我猜测存在某种名称空间分辨率,当存在冲突时,数据段中的变量将覆盖块结构化段中的变量。

如果你要宣布

int a = 5 int a = 10

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


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.不需要extern(或者可能不存在 - 不太确定)的时候。

换句话说,所有具有相同名称的全局变量都将转换为一个变量 - 所以你的

#include<stdio.h>

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

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

© www.soinside.com 2019 - 2024. All rights reserved.