当前位置: 首页 > news >正文

编译过程 多个.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

#include"add.h"intadd(inta,intb){returna+b;}

main .c

#include<stdio.h>#include"add.h"intmain(){inta=6;intb=7;intsum=add(a,b);printf("sum=%d",sum);}

我们将 实现两数相加的add 函数 ,实现放在.c 文件中函数声明放在 .h文件中

我们需要借助 gcc 来窥探 当一个 .c文件包含头文件,且在预处理的过程中会发生什么。

当我们执行如下语句

gcc -E main.c -o main1.i

我们会得到 一个 main1.i 的 c文件
使用

cat main1.i

查看文件包含内容

#4"add.h"intadd(int,int);#4"main.c"2intmain(){inta=6;intb=7;intsum=add(a,b);printf("sum=%d",sum);}

我们发现 main1.i 将 add头文件的内容 展开了。 (实际上,为了展示的需要我们省略了 stdio.h
头文件所展开的代码)

我们再对 add.c 进行预处理

gcc -E add.c -o add1.i

查看add .i 文件代码

cat add1.i
1"add.h"1intadd(int,int);#2"add.c"2intadd(inta,intb){returna+b;}

可见 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 链接时所需要的库
http://www.jsqmd.com/news/1187936/

相关文章:

  • 智能游乐项目别让顾客等搭子:双人PK和单人AI,一套设备都能接
  • 通达信缠论画线神器:5分钟实现智能技术分析
  • 如何轻松获取3大APK历史版本:APKMirror客户端深度体验指南
  • Snap.Hutao:为《原神》玩家量身打造的智能数据管家
  • 适合高职学生的AI短剧漫剧学习实训平台有哪些?深度解析与案例分享 - 客啦啦视界
  • 2026年深圳离婚家事律师推荐:行业靠谱律所排名 - 逻辑孤岛
  • 如何快速部署企业级无人机身份识别:ArduRemoteID开源方案终极指南 [特殊字符]
  • 2026筑宅安|常州外墙漏水专业维修,蜘蛛人高空作业根治墙面渗水发霉 - 筑宅安
  • 用AI做项目回顾:从事散时间线到五问根因的端到端Postmortem自动化方案
  • 2026南京闲置腕表变现指南,手表回收与典当两种处置方式优劣分析 - 禹竞奢收行
  • [Activiti] Idea流程图中文乱码问题
  • Access:从零到精通的SQL实战指南
  • 三分钟让你的Windows搜索框颜值飙升!BeautySearch终极美化指南
  • 最长无重复子串:从暴力到最优,AI 的直觉进化链
  • 雷达中国区官方售后服务中心|最新网点地址及官网热线权威公布(2026年7月最新) - 亨得利客户服务中心
  • 2026西安钻石回收常见问题解答:4C证书怎么算价?易奢福78店专业估价 - ys韩
  • Demo 跑得欢,上线就炸锅:普通程序员在大模型时代的生存真相
  • Axure RP中文界面终极指南:三分钟让英文原型工具变中文
  • 计算机毕业设计之基于springboot的教学辅助平台
  • # 2026北京闲置奢侈品包包回收真实测评|实体店行情透析与高效变现指南 - 名表行情观察
  • Bilibili World现场,NVIDIA祭出史上最夯“轻薄本”RTX Spark
  • GitHub加速终极指南:3分钟解决国内访问GitHub缓慢的完整方案
  • 终极指南:Snap Hutao - 免费开源的原神Windows工具箱,让你的游戏体验提升300%
  • 告警和数据监控系统
  • Word文档自动化——Apache POI实战指南
  • 亨得利中 国官方售后服务体系全解析|官方网站权威公示(2026年7月最新) - 亨得利客户服务中心
  • 2026年7月亲身探访福州亨得利官方名表服务中心|全部地址与售后服务电话 - 亨得利官方
  • javascript思维导图(更新中)
  • 第四十五篇,杂记(五)
  • 代理记账财税服务获客闭环:先用BBWEYY搭建小程序再做GEO,全程零代码,BBWEYY:AI+SAAS+GEO模式