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