一个全局变量在C语言中可以有一到两个不同的存储类,据我所知,声明可以用两个不同的关键字,对应
extern int foo; //default
static int bar;
静态变量只在声明的模块中可见,不能被导出。在extern声明的情况下,变量位于所有链接模块的公共命名空间中,除非被静态变量遮蔽。
静态变量必须在其模块中定义,外部变量可以在其他地方定义。如果要使用它,必须定义它。
我的编译器接受
static int bar = 5;
但是在
抛出一个抱怨extern int foo = 4;
外部变量似乎不应该用关键字'extern'来定义。这导致了以下问题:
在上面的例子中,对象'foo'在定义它的模块中有什么样的存储类?
IIRC, extern
更多的是对编译器的一个暗示,即它不必为该值分配存储空间。链接器需要在另一个编译单元中找到该值。通常在头文件中使用extern
来表示某人已经定义了与该名称相关的存储。该值的定义不包含extern
关键字,因为编译器必须在包含该定义的编译单元中为该值分配存储空间。
外部变量将在定义它的单元中使用全局作用域(导出)定义:
默认为auto
。
实际上您错过了两个存储类:auto和register
寄存器在这里并不重要,但是默认的存储类是auto。
Auto在内存的某个地方为变量保留空间(这通常是您在声明变量时想要的)。应该注意的是,对于"auto variables",每次输入变量的作用域时都会分配新的空间。(也就是说,当func()声明了一个'auto'变量时,从func()内部调用函数func()会产生两个不同的变量,并且每次调用func()只会知道它自己的变量。)由此可见,在全局作用域中声明的auto变量将是唯一的(因为作用域只进入一次)。
然而,静态变量总是唯一的。唯一的意思是空间只分配一次。当func()调用func()并且你希望两个函数调用操作同一个变量时,这是很有用的。
外部变量只是对唯一变量的引用。
当你想要访问在另一个文件中声明的全局变量时,你可以使用这些。
对于文件1.c和2.c,在两个文件中声明"int global;"是不够的,因为空间会被分配两次,并且名称冲突会导致链接错误。
因此,您所做的是在一个文件中保留空间(使用"int global;"),并在另一个文件中告诉链接器在另一个文件中查找名为"global"的变量,写入"extern int global;"。