我试图了解 C 全局变量在多个文件(编译单元)之间共享的方式。我已经阅读了精彩的问答here https://stackoverflow.com/questions/1433204/what-are-extern-variables-in-c。然而,在做了一些测试之后,我仍然有一些我没有得到的东西:
基本上我的问题是:如果在标头中声明了一个变量(但未定义),而没有extern
关键字,是否可以简单地将该标头包含在各个编译单元中以使该变量可用于所有这些编译单元?在这种情况下,这意味着一个(且只有一个)编译单元包含用于初始化(定义?)该变量的代码,并且在其他编译单元尝试对该变量执行任何操作之前将首先调用它。如果这一切都是真的,那么这个过程就是所谓的“隐式外部”吗?
我将用一个例子来说明我的问题:
标头“MyCommonHeader.h”包含:
//MyCommonHeader.h
int* i; //pointer to an int
文件 MyFirstHeader.h 包含:
//MyFirstHeader.h
void changeIt(int newValue);
文件 MyFirstSource.c 包含:
//MyFirstSource.c
#include "MyFirstHeader.h"
void changeIt(int newValue) {
*i = newValue;
}
文件 MySecondSource.c 包含:
//MySecondSource.c
#include "MyCommonHeader.h"
#include "MyFirstHeader.h"
void main() {
i = malloc(sizeof(int));
changeIt(10);
*i = 23;
}
上面的代码是否在所有地方都使用相同的 i 变量进行操作?我需要添加吗extern
任何地方?
/* file.h */
int* i;
是一个暂定的定义i
多变的。这意味着如果翻译单元中该变量没有其他(外部)定义,则它将仅定义一次(初始化为0
)。如果恰好有一个匹配的(外部)定义i
在翻译单元的其他地方,将使用该定义,并且上面的暂定定义将充当声明。
作为一种常见的扩展,编译器跨翻译单元扩展了这种行为。这意味着,对于此类编译器,您可以安全地将该头文件包含在任意多个翻译单元中,并且仍然只有一个定义i
.
如果您还显式初始化了,情况会有所不同i
在头文件中:
/* file.h */
int* i = 0;
这是一个实际的定义(不是暂定的),您只能将该头文件包含在一个编译单元中,否则您会收到多重定义错误。
更好的方法是在 .c 文件中定义变量,然后使用extern
在头文件中:
/* file.h */
extern int* i;
/* file.c */
int* i = 0;
这非常清楚地表明只有一个定义(.c 文件中的定义),并且包含头文件的每个编译单元都将引用该定义。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)