C中主要变量的范围
考虑一下代码:
#include int x; int main (void) { }
main
的x
值为0
。 但那是为什么呢? 我没有声明它是static
。 或者它是否在函数外部被假定为static
?
如果上述情况属实,它如何使它与extern
不同?
它既不是static
也不是extern
。 它是一个变量,对于它所在的编译单元是可见的,并且还可以从声明x
为extern
变量的所有编译单元中看到它。
为什么我说它既不是static
也不是extern
?
如果它是extern
,则必须有一个带有x
声明的不同编译单元。 显然这是你唯一的编译单元。
如果它是static
则不允许对此编译单元中定义的x
变量进行extern
引用。 我们知道我们可以很容易地向这里声明的x
声明一个extern
变量。
为什么0
分配给x
? 因为,在C中 ,所有全局变量都初始化为0
。 它在C99标准的6.7.8(10)中这样说。
当我们说“静态存储持续时间”的变量被隐式初始化为0时,我们并不意味着您需要将“static”关键字放在它们前面。
“静态存储持续时间”仅仅是对象的特定存储持续时间,表示其存储持续整个程序的持续时间。 这种存储持续时间用于在文件范围(如您的变量)和本地静态变量中声明的变量。
6.2.2 / 5:“如果对象的标识符声明具有文件范围而没有存储类特定,则其链接是外部的。”
但这是联系 ,而不是范围 。 您的x
声明将具有文件范围。 static
和extern
不影响范围。 它被初始化为0,因为x
具有静态存储持续时间(见6.2.4 / 3和/ 5)。
一般来说,您还必须了解6.2.2./4:
对于在存储类规范外部声明的标识符,在该范围内可以看到该标识符的先前声明,如果先前声明指定内部或外部链接,则后面声明中标识符的链接与链接相同在先前的声明中具体说明。
因此,使用extern
声明与使用没有存储类说明符的声明并不完全相同。 但是,在您的示例中,没有事先声明。
这不是一成不变的。 这是全球性的。 您可以在不同的编译单元中将其声明为extern
,但是在此单元中将为其分配空间。 顺便说一下,如果Globals没有给出初始化器,它们总是被初始化为0。
您的编译器将x的值初始化为0。
它是一个全局变量,从main()
可见
x是一个全局变量,它在程序启动时为它分配空间并初始化为0(通常,你应该有一个显式的初始化程序)。
‘static’关键字有两种不同的含义。
1)
static int x; int main(){}
这将x的范围限制为单个文件。 虽然它仍然是一个全局变量,但链接器将无法从其他文件连接对x的引用。
2)
int main(){ static int x; }
这有效地将x转换为全局变量。 虽然范围仍然在main函数内,但是全局为它分配空间,并且在调用main()之间保留它的值。
这感觉就像是一个家庭作业问题,但无论如何我会咬人。
要使用您在其他文件的类或函数中定义的x,您可以使用
extern int x;
高于你对x变量的使用(比如在标题中),你可以像在main()中一样使用x。 extern告诉编译器您正在使用在别处定义/实例化的变量。
如果你希望它在main运行之前存在,那么你使用在main()运行之前处理的static。 换句话说,它在开始任何处理之前用变量加载内存空间(在main中)。
至于为什么它在启动时为0,那很可能只是你的编译器给它一个基值。 并非所有的编译器都这样做,除非我弄错了,很多人只会给你分配给x的内存空间中的任何东西。 换句话说,它们会事先为您提供内存中包含的任何数据(或部分数据)。