多文件编程:
当程序的业务逻辑越来越复杂,代码量越来越多,就需要多人组成团队协同开发,那么就必须把任务拆分成若干个文件。
一般的拆分方案:
1、main.c 只当作程序的入口,不实现业务逻辑代码。
2、用于实现程序具体的业务逻辑代码,按照功能拆分成若干个模块
模块名.h 用说明.c文件中有哪些函数、全局变量,也就是函数声明、全局变量声明。
模块名.c 具体的函数实现,全局变量定义。
注意:为了保证声明与定义的一致性,一般 模块名.c 文件一定要包含 模块名.h 文件。
注意:不需要被其它.c使用的函数、全局变量,可以不在.h文件中声明,另外为了防止命名冲突、调用,定义时可以用static修饰。
3、项目中常用的、通用的工具,宏函数、函数
tools.h
tools.c
4、只用于类型设计type.h
结构体、联合、枚举、宏常量、宏函数
头文件中可以写什么:
由于头文件可能会被若干个.c文件包含,那么每包含一次,.c文件中就会有一份头文件的内容,所以头文件中的内容必须可重复,因此我们只适合在头文件中实现以下内容:
1、头文件卫士
2、#include 语句
3、宏常量、宏函数
4、全局变量的声明(变量的声明可以有多份,但定义只能有一份)。
5、函数声明
6、结构、联合、枚举复合的类型设计
7、类型重定义
头文件包含可能出现的问题:
注意:头文件卫士只能解决重复包含的问题,但无法解决相互包含、递归包含的问题。
互相包含:
a.h #include "b.h"
b.h #include "a.h"
递归包含:
a.h #include "b.h"
b.h #include "c.h"
c.h #include "a.h"
解决这种问题的文件,再设计一个.h文件,把他们共用的内容,实现在新的.h文件中,被他们共同包含即可。
多文件编译过程:
1、gcc xxx.h 检查头文件是否有语法错误,如果没有语法错误,会生成xxx.h.gch,检查完毕后该文件要立即删除。
2、gcc -c xxx.c 把.c文件编译成二进制目标文件
3、gcc *.o 把所有目标文件合并成可执行文件,也可以使用-o 设置可执行文件的名字。
Makefile脚本
什么是Makefile脚本
Makefile脚本集合了程序的编译指令的文件,make是一个命令工具,当执行make命令时,它会自动读取Makefile中的编译指令并执行,会自动完成整个项目的自动化编译工作。
为什么需要Makefile脚本:
项目中如何有很多.c文件,它们的编译指令会有很多,需要的编译时间比较长,依赖关系非常复杂。
当项目中的.h文件被修改时、.c文件,我们无法人为的分辨出哪些文件需要重新编译,只能全部重新编译一下,但这项操作非常耗时。
使用Makefile脚本编译项目的好处
1、节约时间 2、记录文件之间依赖关系 3、自动化执行编译过程
Makefile脚本的原理
Makefile脚本的原理就是基于文件最后修改时间,被依赖文件的最后修改时间晚于目标文件,该文件就需要重新编译。
tools.o 依赖 tools.c tools.h
Makefile脚本的格式
由若干个编译目标组成,它类似C语言中的函数,就是若干个编译指令组成的编译模块,默认只执行排在第一个的编译目标,也叫入口目标。
target ... : prerequisites ... command ... ... target:编译目标,它如果不存在,或者早于它依赖的文件,那么就执行该下面的编译指令。 prerequisites:被依赖的编译目标、文件,相当于C语言虽的函数调用。 command:编译指令
contacts: main.o contacts.o tools.o gcc main.o contacts.o tools.o -o contacts main.o: main.c tools.h contacts.h gcc -c main.c contacts.o: contacts.c contacts.h tools.h gcc -c contacts.c tools.o: tools.c tools.h gcc -c tools.c
在Makefile脚本中可以使用变量
变量名=value 定义变量并给变量赋值初值
$(变量名) 使用变量名,获取出变量的值
常用的变量名: CC=编译器 STD=语法标准 FLAG=检查标准,-Wall,-Werror TARGE=最终可执行文件的名字 OBJECT=所有的目标文件名
负责清理的编译目标
该编译目标一般负责删除目标文件、头文件的编译结果、可执行文件。 一般它不会被依赖,也就是不会执行,而是当需要时,在命令行通过make 目标名,手动执行。 什么时候需要它执行: 1、刚修改的内容,并没有发生变化,有可能是依赖有问题,代码并没有重新编译,执行它就可以删除所有目标文件、可执行文件,重新编译。 2、更换了执行平台后,那么之前编译出的目标文件就全部不能再继续使用。 3、项目最终上线时,会把所有的编译结果删除,重新编译。
clean: rm -rf $(OBJECT) $(TARGE) rm -rf .h.gch
通用的Makefile脚本
CC = gcc STD = -std=gnu99 FLAG = -Wall -Werror TARTE = contacts OBJECT = main.o contacts.o tools.o all: $(OBJECT) $(CC) $(OBJECT) -o $(TARTE) %.o:%.c $(CC) $(STD) $(FLAG) -c $< clean: rm -rf $(TARTE) rm -rf $(OBJECT) rm -rf *.h.gch # 缺点:依赖规则无法描述完整