C语言头文件详解

1. GCC编译时问题

在由多个C语言文件组成的程序中,对于头文件的管理非常重要。头文件提供给用户一个接口,用户从中可以知道可以调用哪些函数,实现哪些功能,而不必去管这些功能的具体实现。因此,写好头文件是非常关键的。在头文件中,最常见的问题是"头文件的重复包含"。其意思是同一头文件被源文件包含多次。例如,定义了头文件test1.h和test2.h,其中test2.h包含test1.h,在test3.c中包含了test2.h,那么会造成test3.c对test1.h包含两次,导致重复包含问题。如果在test1.h定义了变量,在gcc编译时就会报"变量重复定义"错误。注意:这里是gcc编译错误。gcc编译过程和链接过程是不相同的过程。在这里需要使用下面的宏进行定义:

#ifndef _TEST1_H_
#define _TEST1_H_
/*头文件内容*/
#endif

解释: 这三条指令是预处理指令,表示如果没有定义_TEST1_H_,就定义_TEST1_H_.

为了说明它的作用,以test1.h, test2.h和test3.c为例子,当test3.c包含test1.h和test2.h会出现下面的情形:

#ifndef _TEST1_H_
/*头文件内容*/
#define _TEST1_H_
#endif
#ifndef _TEST1_H_
/*头文件内容*/
#define _TEST1_H_
#endif

第1次,由于没有定义_TEST1_H_,所以进行定义。当定义_TEST1_H_后,ifndef不会执行。所以,解决了头文件重复包含问题。

注意: (1) 关于_TEST1_H_也可以使用别的名字,没有规定。一般是在头文件名前加_,后加_,中间的.变成_。因为头文件是唯一的,这样,能保证唯一性。

          (2)上面几条语句是预处理命令,在编译前完成。

          (3) #include关键字只是简单的替换,将头文件替换到源文件位置。其实,#include 任何文件    都是合法的。

以上几条预处理命令能够保证gcc编译时出现头文件重复包含导致变量重定义错误。


2.  GCC链接时问题

当我们在test1.h定义了全局变量 int i=10;(这一定是定义,关于“定义”和“声明”区别以后会介绍)。在test1.c 和 test2.c分别了包含了头文件,test3.c使用test1.c和test2.c的相关函数,当使用下面的命令进行编译和链接:

 gcc -c  test3.c -o  test3.c  -Wall  //编译时不会出现“重定义”,ifndef解决此问题

gcc -o  test3 test3.o  test1.o  test2.o  //链接时出现“重定义”,test1.o和test2.o中的i重定义

这是由于在链接过程中,GCC会在全局范围内检查符号,当检查到test1.o和test2.o都存在符号i,显然出现了重定义。

因此,在头文件中不要定义(请记住是定义,和声明区别很大)全局变量。


3. 总结

(1)头文件重复包含可用ifndef来解决,主要是编译时报错,编译的过程主要是检查代码是否符合C语言基本语法。

(2)如果在头文件定义全局变量,在链接时可能会出现重复定义错误。

(3)建议: 在头文件使用extern声明变量或函数,在其中一个源文件进行定义变量或函数,在其它的源文件使用变量或函数。





猜你喜欢

转载自blog.csdn.net/chenjin_zhong/article/details/12025535
今日推荐