C中主要变量的范围

考虑一下代码:

#include  int x; int main (void) { } 

mainx值为0 。 但那是为什么呢? 我没有声明它是static 。 或者它是否在函数外部被假定为static

如果上述情况属实,它如何使它与extern不同?

它既不是static也不是extern 。 它是一个变量,对于它所在的编译单元是可见的,并且还可以从声明xextern变量的所有编译单元中看到它。

为什么我说它既不是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声明将具有文件范围。 staticextern不影响范围。 它被初始化为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的内存空间中的任何东西。 换句话说,它们会事先为您提供内存中包含的任何数据(或部分数据)。