为什么使用static、extern和不使用static声明的变量包含不同的值

Why does variable declared with static, extern and without it contains differenr values

本文关键字:static 变量 包含不 extern 为什么 声明      更新时间:2023-10-16

考虑以下代码片段:

#include <stdio.h>
int a=5;
int main ()
{
    extern int a;
    printf("%dn",a); //5
}
//---------//
#include <stdio.h>
int a=5;
int main ()
{
    static int a;
    printf("%dn",a); //0
}
//---------//
#include <stdio.h>
int a=5;
int main ()
{
    int a;
    printf("%dn",a); //12497123435
}

我不明白为什么用extern说明符声明a时显示5 ?当我们用static修饰符声明a时,alinkage, a可以表示为另一个作用域的实体。

当您编写extern int a;时,您声明了一个具有外部链接的名为a的变量,但您没有定义它。相反,定义必须存在于其他地方——通常在不同的翻译单元中。在这种情况下,a的定义在同一个翻译单元中,声明是完全多余的,因为a已经可见。也就是说,冗余声明不是错误,因此它的行为方式与声明根本不存在一样。如果定义在不同的翻译单元中,则需要声明,以便编译器知道该变量存在。在这两种情况下,extern声明都不引入新变量,a只是引用全局变量。

然而,

static int aint a是定义,并引入了一个名为a的新变量,因此全局变量a的值不再相关。

static int aint a的区别在于它们有不同的存储空间。int a具有自动存储功能,使用带有自动存储功能的未初始化变量会调用未定义的行为,这就是为什么在这种情况下会得到一个"随机"值。另一方面,具有静态或外部链接的变量会自动初始化为0,所以这就是静态变量为0的原因。

您的第一个示例的行为符合预期,并且完全合理。后面两个例子只是bug。在这两种方法中,您都创建了一个名为a的新变量,并在设置它的值之前读取它的值。

extern int a只是一个声明(即公告),名称为a的变量是在其他地方定义的,在您的情况下指的是全局变量。

static int a 定义了一个具有静态存储时间的变量。这种持续时间的变量是零初始化的(静态的)。

int a(函数作用域中)定义了具有自动存储时长的 a。它未初始化。读取其值会调用未定义行为(UB) —第三个示例很危险,因为它调用了UB。