在头文件中定义变量- C

7 浏览
0 Comments

在头文件中定义变量- C

假设我有一个包含三个源文件(.c文件)的项目,并且这三个文件都包含了"file.h",也就是说,在每个文件的开头我写了#include "file.h"。

在file.h文件中,我写了int num=4。

我遇到了一个常见的问题。当我写了int num时,它编译通过。

问题出在哪里?为什么不初始化的情况下也能工作?

(我正在使用Eclipse)

0
0 Comments

在C语言中,头文件(header files)对于编译器来说没有任何特殊的语义,它们只是会被预处理器内联展开的文本。这意味着你在头文件中定义的变量将会被链接器看到三次。为了避免混淆,链接器不知道这三个值中哪一个是正确的。即使它们这一次碰巧有相同的值,链接器还是愚蠢的,并不知道这一点。

如果你只是有一个"int num;",这是一个特殊情况,变量会被分配为common而不是data,链接器知道在最终的链接阶段统一common。一般来说,我会说使用common是不好的形式,头文件应该只有"extern int foo;",而变量本身只在一个链接单元中定义。

原因:

在C语言中,头文件通过预处理器展开后会被多次看到,这会导致链接器不知道变量的定义到底是哪一个正确的值。

解决方法:

避免在头文件中定义变量,应该将变量的声明放在头文件中,而将变量的定义放在一个链接单元中。这样可以避免链接器对变量定义的混淆。

示例代码:

// header.h

extern int num; // 变量的声明

// source1.c

#include "header.h"

int num = 10; // 变量的定义

// source2.c

#include "header.h"

int num = 20; // 变量的定义

这样,通过将变量的声明放在头文件中,变量的定义放在一个链接单元中,就可以避免链接器对变量定义的混淆,确保只有一个正确的值被链接到最终的程序中。

0
0 Comments

在C语言中,可以多次声明全局变量,但是只能在一个翻译单元中初始化。因此在file.h文件中,可以写下

extern int num;

,然后在file.c文件中写下

int num = 4;

。需要确保只在一个C文件中包含最后一行代码,其他文件将使用该一次出现的值。

如果在头文件中没有将变量声明为extern关键字,会发生什么呢?这是定义全局变量的方式。即使没有使用"extern"关键字,这种方式似乎也可以正常工作。那么到底会发生什么呢?

"extern"关键字声明了一个变量或者函数,并指定它具有外部链接(其名称可以在其他文件中可见)。当修改一个变量时,extern指定该变量具有静态持续时间(在程序开始时分配,在程序结束时释放)。变量或函数可以在另一个源文件中定义,或者稍后在同一文件中定义。默认情况下,文件范围的变量和函数声明是外部的。

所以,如果在其他两个源文件中写下"int num"而不初始化它,这样做也是完全可以的吗?这取决于你想要实现什么。这就像在定义函数之前声明函数一样。

如果你写下int num,你是告诉编译器“请保留一些内存并将其与给定的名称关联起来”。如果你写下extern int num,那么你是告诉编译器“将会有某人在该名称下保留内存,可以自由使用它”。因此,如果没有使用extern关键字,将会有多个具有相同名称的内存位置,导致链接问题。

0