如果要使用全局变量,为什么需要将全局变量声明为`extern`?

时间:2019-05-17 15:49:54

标签: c variables syntax

我了解默认情况下C中的文件作用域变量为{ "/someDomain/service/common/myService": { "target": "http://localhost:3000/myService", "logLevel": "debug", "pathRewrite": { "^/someDomain/service/common/myService": "" } } } -即使未明确指定(如对Global variables in C are static or not?的答复中所述)。

但是,我还知道,如果extern声明为a.h,并且extern int x = 10;要访问b.c,则需要将其声明为x。 / p>

为什么会这样?为什么不只访问extern而没有其他x的东西呢?这种机制的技术解释是什么?

3 个答案:

答案 0 :(得分:1)

因为变量在文件外部;它是在另一个文件中定义的,您只是告诉该文件存在,但在该文件中找不到它。然后,链接程序的任务就是解决这个问题。

示例:

// a.c
int x = 7;

a.c定义了变量

// a.h
extern int x;

a.h知道该变量存在,但不知道在哪里。任何包含a.h的文件都将获得该知识

// b.c
#include "a.h"

b.c因为包含了a.h,所以现在知道变量x存在,但是不知道在哪里。

链接器将解析相同变量x的那些不同用法。它们最好一样,否则会出问题。

您可能撒谎,写一个float而不是int,只有链接器可能会注意到这一点,因为编译器从字面上不了解ac(嗯,ac应该包含ah,因此它会注意到,但是如果您不包含它,您可能会撒谎)

在整个项目中,每个变量必须有一个且只有一个非外部定义。 0或2或更多,链接器将报告错误。

答案 1 :(得分:1)

全局变量的存储仅分配一次。例如,在main.c中:

int gMyCounter;

在要使用或访问此变量的任何其他模块(C文件)中,必须将其存在和类型告知编译器。您可以使用extern关键字来完成此操作,例如在mymodule.c中:

extern int gMyCounter;

在链接期间,链接器看到mymodule.o需要变量gMyCounter并在其他.o文件和库中进行搜索。它在main.o中找到它。

答案 2 :(得分:0)

头文件a.h不应包含

extern int x = 10;

但只是

extern int x;

然后文件a.c应该定义

int x = 10;

并且当文件b.c要使用x时,它应该简单

#include "a.h"

,编译器在编译b.c时会知道x是在其他地方定义的,链接器将找到该引用并进行修复。


从添加的链接中进行编辑:如果定义位于编译器看不到的编译单元中,则该变量不会神奇地变为可用:您需要将其声明为extern,以便编译器可以看到它,因此它知道它将可用。它的作用与功能原型的目的相同:它只是定义,而不是定义。