编译过程 多个.c文件 . h文件 和main文件的 联系 问题多文件编写时为什么 多个.c 文件可以组合成为一个main.c 文件换句话说 主文件 main.c 怎么实现 将 多个 .c文件 整合而且是以包含这些 .c 文件的头文件 的方式 而不是包含 其他 .c文件的方式下面我以add.cadd.hmain.c文件为例add.h#ifndef__ADD__#define__ADD__intadd(int,int);#endif/*__ADD__*/其中add.c#includeadd.hintadd(inta,intb){returnab;}main .c#includestdio.h#includeadd.hintmain(){inta6;intb7;intsumadd(a,b);printf(sum%d,sum);}我们将 实现两数相加的add 函数 实现放在.c 文件中函数声明放在 .h文件中我们需要借助 gcc 来窥探 当一个 .c文件包含头文件且在预处理的过程中会发生什么。当我们执行如下语句gcc -E main.c -o main1.i我们会得到 一个 main1.i 的 c文件使用cat main1.i查看文件包含内容#4add.hintadd(int,int);#4main.c2intmain(){inta6;intb7;intsumadd(a,b);printf(sum%d,sum);}我们发现 main1.i 将 add头文件的内容 展开了。 实际上为了展示的需要我们省略了 stdio.h头文件所展开的代码我们再对 add.c 进行预处理gcc -E add.c -o add1.i查看add .i 文件代码cat add1.i1add.h1intadd(int,int);#2add.c2intadd(inta,intb){returnab;}可见 add.c 在预处理之后也会将 头文件展开当我们把main.c 和add.c 都进行 预处理的时候 他们都将会拥有 add 的头文件所包含的那部分代码这样main .c 就和 add.c 建立起了联系。当 存在多个像add .c 这样的 .c文件 多个像 add.h这样的 .h 文件时 且main.c 同样包含了所有的.h 每个.c 文件同样包含了与其对应的头文件 时。 我们就能发现 main .c 通过 .h 文件 引用到了 其他.c 文件中的 代码实现代码简言之.h文件中的所有内容会被写到包含它的.c文件中而所有的.c文件以一个共同的main函数作为可执行程序的入口。具体的解释比方说 我在add.h里定义了一个函数的声明然后我在aaa.h的同一个目录下建立add.c add.c里定义了这个函数的实现然后是在main函数所在.c文件里#include这个add.h 然后我就可以使用这个函数(add.c))了。main在运行时就会找到这个定义了这个函数的add.c文件。这是因为main函数为标准C/C的程序入口编译器会先找到该函数所在的文 件。假定编译程序编译myproj.c(其中含main())时发现它include了mylib.h(其中声明了函数void test())那么此时编译器将按照事先设定的路径(Include路径列表及代码文件所在的路径)查找与之同名的实现文件(扩展名为.cpp或.c此例中为mylib.c)如果找到该文件并在其中找到该函数(此例中为void test())的实现代码则继续编译如果在指定目录找不到实现文件或者在该文件及后续的各include文件中未找到实现代码则返回一个编译错误.其实include的过程完全可以“看成”是一个文件拼接的过程将声明和实现分别写在头文件及C文件中或者将二者同时写在头文件中理论上没有本质的区别。需要明白的是 每一个 .c文件都是一个 编译单元当多个.c 文件经历 预处理、编译、汇编 (test.c test.h test.i test.s test.o最终转变为多个 .o 文件时 。就要经历 链接这一步了连接阶段将各个目标文件中的各段代码进行绝对地址定位生成跟特定平台相关的可执行文件编译器在编译时是以C文件为单位进行的.也就是说如果你的项目中一个C文件都没有那么你的项目将无法编译连接器是以目标文件为单位它将一个或多个目标文件进行函数与变量的重定位生成最终的可执行文件在PC上的程序开发一般都有一个main函数这是各个编译器的约定。为了生成一个最终的可执行文件就需要一些目标文件也就是需要C文件而这些C文件中又需要一个main函数作为可执行程序的入口。最终的最终我们将多个 .o 文件进行链接 变为可执行文件。最后 以创建静态库 为例我们创建静态库 首先 将多个 .c 文件变成 .o文件然后利用 ar -rcs 指令 生成指定的 静态库最后利用静态库 只需要 静态库静态库包含的头文件 还有你准备用来测试 静态库的 .c文件当然 你的.c 测试文件 需要包含上述的头文件 才能达到测试静态库的目的gcc test.c -I所需要使用的头文件 -L链接库所在目录 -l 链接时所需要的库