何时使用extern
,何时使用标头共享变量?假设以下内容:
test1.h
int a;
test1.c
#include "test1.h"
a = 5
VS
test1.h
extern int a;
test1.c
#include "test1.h"
int a = 5
我还看到人们在头文件中使用extern
来定义全局变量,但是我可以
通过省略extern
并仅使用头文件来获得相同的输出。它可以编译并正常运行。
答案 0 :(得分:0)
使用
int a;
您有一个tentative definition。如果在当前translation unit中未找到其他定义,则为定义,否则为声明。
使用
extern int a;
您只声明变量a
,告诉编译器它将在程序的某个位置找到,无论是在当前翻译单元中还是在另一个翻译单元中。
请注意
extern int a = 5;
是一个实际的定义,就像普通的
int a;
不同之处在于extern int a = 5;
包含变量的初始化程序。
您不能在全局(非功能)范围内使用通用语句。其中包括诸如
a = 5; // Invalid if not inside a function
但是以下内容有效:
int a; // Tentative definition
...
int a = 5; // Actual definition, the above becomes a declaration
最后,在全局(非功能)范围内定义的所有变量都将具有外部链接,无论是否带有extern
关键字:
int a = 5; // Definition with external linkage
extern int b = 5; // Definition with external linkage'
来自this storage duration reference:
如果未提供存储类说明符,则默认值为:
- 所有功能都为外部
- 外部文件范围内的对象
- 自动用于块范围内的对象
[我对相关内容的强调]
答案 1 :(得分:0)
如果在临时定义的范围内将标头包含在多个翻译单元中,则第一种方法可能会导致链接器错误
int a;
在某些翻译单元中没有外部定义。
所有包含标头的翻译单元都将对具有外部链接的变量a具有自己的暂定定义,链接器将确定歧义。
考虑到该记录
a = 5;
不是具有暂定定义的变量的定义。这只是一项任务。
因此,与第一种方法相比,第二种方法更可取。
当标头仅包含在用于小程序的一个翻译单元中时,可以使用第一种方法。
答案 2 :(得分:0)
extern,并且在生成可执行文件时由链接器使用y。猜想:
test1.h
extern int a;
test1.c
#include "test1.h"
Int a;
void somemethod() {
}
test2.c
#include "test1.h"
void otherMethod() {
a=5;
}
在编译方式中,由于包含test1.h,test2.c具有对变量“ a”的外部引用。编译器将此引用留作待处理,以供链接器解决。在链接器阶段,然后在test1.c中找到“ a”,然后链接器确定test2.c中的“ a”是对test1.c中定义的“ a”的引用。注意“ a”是全局的。
如果在test1.h中删除extern,则在构建时会出现多个定义错误,因为test1.c和test2.c具有相同的变量“ a”。因为两个都包含test1.h。我希望了解我。我的英语是这样。或者可以有人描述得更好。