最简单的例子可以参考:http://jingyan.baidu.com/article/6b97984dcfd2991ca2b0bf03.html
头文件是一种文本文件,使用文本编辑器将代码编写好之后,以扩展名.h保存就行了。头文件中一般放一些重复使用的代码,例如函数声明,变量声明,常数定义,宏的定义等等。当使用#include语句将头文件引用时,相当于将头文件中所有内容,复制到#include处。使用头文件不仅可以减少工作量,还可以减少因代码编写不细心而导致的错误。
源文件定义的函数,在源文件对应的头文件中声明,然后源文件包含自己的头文件。这样定义和声明就放在同一个文件里了。
援引上述例子:a.c中定义了函数sum,而函数本质上是外部的,函数sum是可以被其它源文件调用的。那么,我们把sum函数的声明放在a.h中。然后a.c源文件还要包含自己的头文件,也就是a.h文件。而b.c文件要引用sum函数,就直接包含a.h文件就可以。
sum函数的定义在a.c中,声明是在a.h中,但是由于a.c包含了a.h,所以sum的定义和声明就是在同一个文件a.c中了。这样,编译器编译的时候,就能对sum函数定义和声明的一致性做检查,如果不一致,就会报错。
至于其他源文件引用这个外部函数sum,不再采用直接声明的方式,而是通过包含a.h头文件的方式。
这样,编译器检查了sum函数定义和声明的一致性没有报错,也就表明a.c中sum函数的定义和a.h中sum函数的声明是一致的。那么其他源文件都是通过直接包含a.h,来使用函数sum,就也保证了sum函数声明和定义的一致性了。
结论
c源文件要包含自己的头文件,目的就是让编译器检查定义和声明的一致性
一、gcc编译的流程
预处理(Pre-Processing) -> 编译(Compling) -> 汇编(Assembling) -> 连接(Linking)预处理:处理#include、#define、#ifdef 等宏命令
编译:把预处理完的文件编译为汇编程序.s
汇编:把汇编程序.s编译为.o二进制文件
链接:把多个二进制文件.o集合(链接)成一个可执行文件
1. 多头文件.h时,在预处理阶段处理,指明头文件所在地址,但通常在makefile中是一个命令完成到第3步,生成.o
2. 多源文件.c时,在链接阶段处理,gcc命令要写出所有源文件,不然会出现引用了却未定义的函数\变量等
二、多文件,多头文件时的gcc经验分享
情况1、一步直接由.c生成执行文件
gcc [-I包含文件.h的目录1 -I包含文件.h的目录2...] 源文件1.c [源文件2.c 源文件3.c...] -o 执行文件名情况2、先编译成.o,再由.o链接为执行文件(makefile中常见,因为在大型项目时,可以实现重编译部分文件而不需要每次都全部编译源文件文件)
a、gcc [-I源文件1包含的文件.h的目录] 源文件1.c [-o 源文件1.o]
//可以通过-o指定生成的二进制文件地址和位置
gcc [-I源文件2包含的文件.h的目录] 源文件2.c [-o 源文件2.o]
....
b、gcc 源文件1.o 源文件2.o ...... -o 生成的执行文件(默认为a.out)
示例如:http://blog.csdn.net/gmpy_tiger/article/details/50903620
linux下Makefile的编写及示例:http://blog.csdn.net/wangkuifeng0118/article/details/7282530
多个头文件和源文件的linux内核编程Makefile编写:http://blog.csdn.net/cfc1243570631/article/details/9138583