为什么使用static、extern和不使用static声明的变量包含不同的值
Why does variable declared with static, extern and without it contains differenr values
考虑以下代码片段:
#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
时,a
有linkage
, a
可以表示为另一个作用域的实体。
当您编写extern int a;
时,您声明了一个具有外部链接的名为a
的变量,但您没有定义它。相反,定义必须存在于其他地方——通常在不同的翻译单元中。在这种情况下,a
的定义在同一个翻译单元中,声明是完全多余的,因为a
已经可见。也就是说,冗余声明不是错误,因此它的行为方式与声明根本不存在一样。如果定义在不同的翻译单元中,则需要声明,以便编译器知道该变量存在。在这两种情况下,extern声明都不引入新变量,a
只是引用全局变量。
static int a
和int a
是定义,并引入了一个名为a
的新变量,因此全局变量a
的值不再相关。
static int a
和int a
的区别在于它们有不同的存储空间。int a
具有自动存储功能,使用带有自动存储功能的未初始化变量会调用未定义的行为,这就是为什么在这种情况下会得到一个"随机"值。另一方面,具有静态或外部链接的变量会自动初始化为0,所以这就是静态变量为0的原因。
您的第一个示例的行为符合预期,并且完全合理。后面两个例子只是bug。在这两种方法中,您都创建了一个名为a
的新变量,并在设置它的值之前读取它的值。
extern int a
只是一个声明(即公告),名称为a
的变量是在其他地方定义的,在您的情况下指的是全局变量。
static int a
定义了一个具有静态存储时间的变量。这种持续时间的变量是零初始化的(静态的)。
int a
(函数作用域中)定义了具有自动存储时长的 a
。它未初始化。读取其值会调用未定义行为(UB) —第三个示例很危险,因为它调用了UB。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- "static initialization order fiasco"是 constexpr 变量的问题吗?
- 使用C 中的链接seam break static变量依赖关系
- 成员变量在 C++17 中标记为'static' static_assert?
- GCC 仍然使用 -fno-threadsafe-static 生成保护变量
- 如果变量在 .h 文件中定义为"static "怎么办?
- "static const char array"可以在 C 语言上包含变量成员吗
- 带有static/const的变量,在本例中使用
- 在 main 中初始化类的 "static const" 类型变量成员的更好方法
- const/static关键字是否在变量声明中传播
- 在没有实例变量的情况下初始化派生类中的"inherited static members"
- 返回静态变量时,static const与static的区别
- 为什么使用static、extern和不使用static声明的变量包含不同的值
- 如果我们在c++中使用static关键字删除[-Wreturn local-addr](警告:返回本地变量的地址),可以
- "static"关键字与类的变量、函数和对象等有什么用?