
个人主页 : 流年如夢
专栏 : 《C语言》
因为要用到 gcc 编译环境,作者本人目前还不会🥹,相关截图没有,可以先大概了解一下,后面学习了会补充完整,请谅解🙏🙏🙏,感谢支持。
文章目录
Ladies and gentlemen,本篇文章讲的是 翻译环境、运行环境、预处理、编译、汇编、链接 全过程,是理解程序底层运行、解决多文件编译问题;全程高能,不容错过!!!
前言
我们写的
.c源代码,无法直接被计算机执行,必须经过一系列翻译步骤,变成可执行程序。这个过程就是编译+链接 。理解编译与链接,能帮助大家搞懂头文件重复包含、宏展开、extern
作用、重定位、符号解析等底层问题,写出更规范、更稳定的多文件项目
一.翻译环境
翻译环境就是把源代码转换成可执行程序(二进制)
其中有四步核心流程👉 :.c --> 预处理 --> .i --> 编译 --> .s --> 汇编 --> .o或.obj --> 链接 --> .exe
更具体的流程图如图所示:

1.1预处理
功能 :
把.i文件 --> 汇编代码.s
主要工作内容:
- 展开
#include头文件,把内容插入进来- 展开
#define宏定义,并删除#define- 删除所有注释
- 处理条件编译
#if#ifdef#endif- 添加行号、文件名,保留
#pragma
指令(在gcc):
c
gcc -E test.c -o test.i
🧐分析 :-E只进行预处理,停止在预处理阶段;-o是输出到指定文件
1.2编译
功能:
把
.i文件 --> 汇编代码.s
步骤:
- 词法分析:拆分关键字、标识符、数字、符号
- 语法分析:生成语法树
- 语义分析:类型检查、匹配
- 优化:生成最优汇编代码
指令(在gcc):
c
gcc -S test.i -o test.s
🧐分析 :-S只进行编译,生成汇编文件.s
1.3汇编
功能:
把汇编代码
.s--> 机器指令(二进制目标文件.o或.obj)
特点:
- 不做优化
- 一条汇编指约等于一条机器指令
指令(在gcc):
c
gcc -c test.s -o test.o
🧐分析 :-c只进行汇编,生成目标文件.o
1.4链接
功能:
把多个
.o或.obj+库文件 --> 可执行文件.exe
主要工作内容:
- 符号解析:找到函数、全局变量的地址
- 重定位:修正所有调用地址
- 地址与空间分配
举个例子:
在add.c文件
c
int g_val = 2022;
int Add(int x, int y)
{
return x + y;
}
在test.c文件
c
#include <stdio.h>
extern int Add(int x, int y);
extern int g_val;
int main()
{
int sum = Add(10, 20);
printf("%d\n", sum);
printf("%d\n", g_val);
return 0;
}
🧐分析 :
test.c单独编译生成test.o;add.c单独编译生成add.o
链接时:找到Add函数地址;找到g_val地址;修正调用指令 --> 重定位完成
二.运行环境
运行环境是执行已经生成好的可执行程序
运行步骤:
| 先把可执行程序加载到内存 |
|---|
⬇️
然后从main函数开始执行 |
|---|
⬇️
| 接着使用栈存放局部变量、函数调用 |
|---|
⬇️
再使用静态区存放全局变量、static变量 |
|---|
⬇️
| 最后程序结束 |
|---|
🎯总结
- 翻译环境 :源代码 --> 可执行程序,四步流程:
预处理(test.c) --> 编译(test.i) --> 汇编(test.s) --> 链接(test.o或.obj),最后到可执行程序(test.exe) - 预处理:展开头文件、宏、删注释
- 编译:生成汇编代码
- 汇编:生成机器码目标文件
- 链接:多文件合并、符号解析、重定位
- 运行环境 :加载内存、执行
main、使用栈与静态区
⚠️易错点
- 以为
.c直接变.exe,不知道四步流程- 混淆编译和链接的职责
- 不知道预处理会删除注释、展开头文件和宏
- 多文件中忘记
extern声明,链接报错- 目标文件
.o或.obj已是二进制,但不能直接运行- 重定位是链接阶段完成,不是编译阶段
👀 关注 我们一路同行,从入门到大师,慢慢沉淀、稳步成长
❤️ 点赞 鼓励原创,让优质内容被更多人看见
⭐ 收藏 收好核心知识点与实战技巧,需要时随时查阅
💬 评论 分享你的疑问或踩坑经历,一起交流避坑、共同进步