1、为什么需要多文件
(1)因为一个真正的C语言项目是很复杂的,包含很多个函数,写在一个文件中不利于查找、组织、识别,所以人为的将复杂项目中的很多函数,分成了一个一个的功能模块,然后分开放在不同的.c文件中,于是乎有了多文件项目。
(2)在任何一个文件中定义的任何一个函数,都有可能被其他任何一个文件中的函数来调用。但是大家最终都是被main函数调用,有可能是直接调用,也可能是间接调用。
2、多文件的编译
- 简单的C语言程序(项目)只有一个C文件(a.c),编译的时候gcc a.c -o a,执行的时候./a
- 复杂的C语言程序(项目)是由多个C文件构成的。譬如一个项目中包含2个c文件(a.c, b.c),编译的时候 gcc a.c b.c -o ab,执行的时候 ./ab
3、C语言的编译过程
(1)预处理: 编译器首先对源代码进行预处理,处理所有的预处理指令,如宏定义展开、条件编译指令等。
(2)编译: 编译器将预处理后的代码转换成汇编语言代码。这一步骤将C语言的高级结构转换为机器可以理解的低级指令。
(3)汇编: 汇编器将汇编语言代码转换成机器码,生成目标文件(Object File),通常以.o
为扩展名。
(4)链接: 链接器将一个或多个目标文件与库文件链接在一起,解决代码中的外部引用,生成最终的可执行文件(Executable File),通常在Unix/Linux系统中以无扩展名表示,在Windows系统中以.exe
为扩展名。
(5)运行: 生成的可执行文件可以在操作系统上运行,执行程序的指令。
编译过程可以通过编译器命令行工具手动执行,也可以通过集成开发环境(IDE)自动完成。在某些情况下,编译流程可能还包括优化步骤,以提高生成代码的性能。
4、头文件
(1)使用头文件可以简化全局变量、全局函数跨文件使用时的声明。
(2)#include包含头文件时,用<>和""的区别
- <xx> 用来包含系统自带的头文件,系统自带指的是不是自己写的,是编译器、库函数或者操作系统提供的头文件。
- "xx" 用来包含项目目录中的头文件,这些一般是我们自己写的。
- 使用<>包含,编译时会先去编译器、库函数中去找,找不到再到项目目录中去找。
反之,使用""包含时,编译时会先去项目目录中去找,找不到再到编译器、库函数中去找。
(3)防止头文件重复包含
#ifndef __xx_H__
#define __xx_H__
/* C语言头文件中的声明 */
#endif
(4)写程序时,不应该在头文件中定义变量。
- 这时该头文件被多个源文件包含时,就会出现重复定义问题。
- 全局变量的定义就应该放在某个源文件中,然后在别的源文件中使用前用extern声明。