C语言编译过程详解:从源代码到可执行文件的四个关键步骤
创作时间:
作者:
@小白创作中心
C语言编译过程详解:从源代码到可执行文件的四个关键步骤
引用
1
来源
1.
https://cloud.tencent.com/developer/article/2474526
C语言的编译过程涉及几个关键步骤、概念和细节,每个步骤都有助于将人类可读的源代码转换为可执行的机器码。以下是详细的解释和示例:
c 编译过程将作为输入的源代码转换为目标代码或机器代码。编译过程可分为预处理、编译、汇编和链接四个步骤。
一、什么是编译?
编译是将源代码转换为目标代码的过程。它是在编译器的帮助下完成的。编译器检查源代码是否存在语法或结构错误,如果源代码没有错误,则生成目标代码。
二、编译过程中的步骤:
- 预处理:
- 概念:预处理器 (cpp) 处理以 # 开头的指令,如 #include 、 #define 和 #ifdef 。它通过展开宏和包含头文件来准备源代码进行编译。
- 细节:将源代码转换为预处理后的中间形式。源代码是在文本编辑器中编写的代码,源代码文件的扩展名为 .c 。此源代码首先传递给预处理器,然后预处理器扩展此代码。展开代码后,扩展的代码将传递给编译器。
- 示例:
- 后缀: .i (生成的预处理后的源文件)。
- 编译:
- 概念:编译器 (gcc, clang) 将预处理后的源代码翻译成特定于目标体系结构的汇编语言。
- 细节:执行词法分析、语法分析、语义分析和优化。由预处理器扩展的代码将传递给编译器。编译器将此代码转换为汇编代码。或者我们可以说 C 编译器将预处理的代码转换为汇编代码。
- 示例:
- 后缀: .s (生成的汇编代码文件)。
- 汇编:
- 概念:汇编器 (as) 将汇编代码转换为可重定位的机器码(目标代码)。
- 细节:将汇编指令转换为机器码指令。使用汇编程序将汇编代码转换为目标代码。汇编程序生成的目标文件的名称与源文件的名称相同。在 DOS 中,目标文件的扩展名是 .obj ,在 UNIX 中,扩展名是 .o 。如果源文件的名称为 hello.c ,则目标文件的名称将为 hello.obj 。
- 示例:
- 后缀: .o (生成的目标文件)。
- 链接:
- 概念:链接器 (ld) 将多个目标文件组合在一起,并解决外部引用,生成最终的可执行代码。
- 细节:执行符号解析、为变量和函数分配最终地址,并链接必要的库文件。主要是,所有用 C 编写的程序都使用库函数。这些库函数是预先编译的,并且这些库文件的目标代码以 .lib (或 .a )扩展名存储。链接器的主要工作是将库文件的目标代码与我们程序的目标代码相结合。有时,当我们的程序引用其他文件中定义的函数时,会出现这种情况;那么linker在这方面起着非常重要的作用。它将这些文件的目标代码链接到我们的程序。因此,我们得出结论,链接器的工作是将程序的目标代码与库文件和其他文件的目标代码链接起来。链接器的输出是可执行文件。可执行文件的名称与源文件的名称相同,但仅在扩展名上有所不同。在DOS中,可执行文件的扩展名为 .exe ,而在UNIX中,可执行文件可以命名为 a.out 。例如,如果我们在程序中使用 printf() 函数,则链接器会将其关联的代码添加到输出文件中。
- 示例:
- 后缀:(可执行文件通常没有特定的后缀,常见的是没有后缀或 .out )。
三、其他概念和细节:
- 编译器优化:提升代码性能和大小。
- 目标文件:包含机器码和符号。
- 静态与动态链接:静态链接库和动态链接库的嵌入与运行时链接。
- 可执行文件格式:各种操作系统特定的格式(如 ELF、PE)。
- .hex
和
.bin
文件通常不是C语言编译过程的直接产物,而是在嵌入式系统开发中常见的文件格式,用于存储程序或数据的二进制表示。这些文件通常是在程序已经编译、链接并生成了可执行文件之后,通过特定的工具或者转换过程生成的。因此,它们不属于C语言编译过程的标准阶段,但是在嵌入式开发中是非常常见的文件格式。 - .hex 文件:通常用于存储以十六进制格式表示的固件或程序映像,适用于多种嵌入式系统和芯片编程器。
- .bin 文件:通常用于存储原始的二进制数据,可以包括程序或者数据文件,常见于嵌入式系统和低级系统编程中。
示例 1 解释:
对于给定的C程序示例:
#include <stdio.h>
#define MAX 100
int main() {
printf("Max value: %d\n", MAX);
return 0;
}
- 预处理:展开 #include <stdio.h> 并将 MAX 替换为 100 。
- 编译:将C源代码转换为汇编语言。
- 汇编:将汇编指令转换为机器码。
- 链接:将机器码与标准库函数(如 printf )结合,生成最终的可执行文件。
示例 2 解释:
#include <stdio.h>
int main()
{
printf("Hello World !");
return 0;
}
现在,我们将创建上述程序的流程图:
在上面的流程图中,执行程序需要执行以下步骤:
- 首先,将输入文件(即 hello.c )传递给预处理器,预处理器将源代码转换为扩展的源代码。扩展源代码的扩展将是 hello.i 。
- 扩展的源代码将传递给编译器,编译器将此扩展的源代码转换为汇编代码。程序集代码的扩展名为 hello.s 。
- 然后,将此汇编代码发送到汇编程序,汇编程序将程序集代码转换为目标代码。
- 创建目标代码后,链接器将创建可执行文件。然后,加载程序将加载执行的可执行文件。
理解这些步骤有助于优化代码、调试问题,并了解C编程中的平台特定细节。
热门推荐
润喉养肺靠「酥梨膏」:乾隆御用的天然食补秘方
什么是EDI(电子数据交换)
Meme币暴富梦背后:1400亿美元市场中的致命税务陷阱
精神病人刑事责任认定
仓鼠饲养指南:如何保持饲养笼的清洁与仓鼠的健康
穿越城市 连接未来 昆明地铁5号线开通运营两年 单日最高客流突破22万
“头要正、肩要平……”西山区教体融合“武”进校园
姚明体重飙升至400斤,从NBA巨星到篮协主席的转变之路
传统中药配方:理中丸、附子理中丸、桂附理中丸——正确使用助力脾胃健康
AI、自动驾驶、脑机接口…盘点2024全球科技界十大“震惊”事件
INFJ和INFP怎么区分?详细对比分析
牙龈有个不痛的“肉疙瘩” , 要处理吗?
18岁中秀才,84岁中进士,他可能是科举史上最强的钉子户了
黑暗之魂3DLC:艾雷德尔之烬 图文攻略全场景收集攻略
化妆品产品经理如何发展
狗狗咳嗽的快速有效治疗方法(教你如何迅速缓解和治疗狗狗的咳嗽问题)
小小香囊,传统文化与绿色健康的瑰宝
LVDS信号传输技术详解:原理、特点及PCB设计要点
炫酷向未来,载人月球车方案再进化
四方玉佩:八方来财的寓意与象征
张雪峰推荐的4所大学,录取分数线暴涨,学生欲哭无泪
红烧羊肉的做法 最正宗的做法,最正宗的做法详解
2025年美国创业攻略:深度解析中美商业环境差异与挑战
投资能力遭质疑?40只主动权益基金924以来还亏钱,知名基金经理不少
《贫穷的本质》:谁在制造贫穷的牢笼?
吃药前血压高,吃过药后血压正常,这样降压达标吗?如何调整?
知识科普:黄精能不能与萝卜同食?
赞美史话 | 09.02_第1首圣哉三一歌
中医直言:肝郁气滞,气大伤身?中医教你这样调理
Docker学习第一弹:初识Docker并安装(图解,超详细!)