头文件并不参加链接和编译。编译器第一步要做的就是简单的把头文件在包含它的源文件中展开。不知你是否能理解这句话。也就是头文件里面有什么内容,通通把它移到包含这个头文件的源文件里。(我觉得这是个很重要的概念,可以帮助我们简化理解编译链接的过程,包括理解头文件中定义静态变量或静态函数是怎么回事)。编译器经过这一步转换后剩下什么呢?就是一堆cpp文件了。而头文件已经不再是编译器需要关心的东西了。编译器接下来就要处理这一堆cpp文件了。
"头文件-源文件"的编译模型:
每个源文件作为一个编译单元,可能会包含上百甚至上千个头文件,而在每一个编译单元,这些头文件都会被从硬盘读进来一遍,然后被解析一遍。
每个编译单元都会产生一个obj文件,然后所以这些obj文件会被link到一起,并且这个过程很难并行。
这里,问题在于无数头文件的重复load与解析,以及密集的磁盘操作。
#ifndef只是防止了头文件被重复包含,但是无法防止变量被重复定义。
在其他文件中只要包含了xxx.h就会独立的解释,然后每个.c文件生成独立的标示符。在编译器链接时,就会将工程中所有的符号整合在一起,由于文件中有重名变量,于是就出现了重复定义的错误。
在 .c文件 中声明变量,然后建一个头文件(.h文件)在所有的变量声明前加上extern,注意这里不要对变量进行的初始化。然后在其他需要使用全局变量的.c文件中包含.h文件。编译器会为.c生成目标文件,然后链接时,如果该.c文件使用了全局变量,链接器就会链接到 此.c文件
注解:c/c++就这么规定:不可以在.h里定义变量,因为就是会触发这个重复定义错误。你只能在.h里用extern
因为#include
#ifndef
#define
#endif
http://www.cnblogs.com/gcpopo/archive/2012/07/18/2598011.html
http://blog.csdn.net/luckyxiaoqiang/article/details/8957617