首页
学习
活动
专区
工具
TVP
发布

详解 C 语言源文件变成可执行文件的过程

很多小伙伴儿在学 C 语言时,用的是 IDE,比如 VS、Code::Blocks 等。每次写完代码点一下运行按钮或者按下相应的快捷键,就可以将程序跑起来,操作非常简单。所以他们就产生了一个错觉:C 语言源代码可以直接运行。

IDE:Integrated Development Environment,集成开发环境,是一个用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器等工具。它为程序开发提供一条龙服务,开发者无需切换使用其他开发工具,可以大幅提升开发效率和体验。

很明显这是错误的,C 语言是一门编译型的语言,其源代码是不能直接运行的,必须通过编译和链接处理,转化为可执行文件后才能运行。这个可执行文件就是我们所说的程序,在 Windows 系统中的文件后缀名为 .exe。

IDE 为了提升开发效率,将背后的细节处理过程都包装起来了,让我们可以一键搞定。但站在技术学习的角度,我们很有必要详细了解一下 C 语言源文件转化为最终可执行文件的整个过程。知其然知其所以然,以后遇到项目构建问题也能自己分析解决。

第 1 步:预处理(Preprocess)

也称为预编译,顾名思义就是在编译之前处理一下,即对源文件(.c)和头文件(.h)里面的所有预处理命令进行相应处理,并删除所有注释内容。所谓预处理命令,就是代码中那些以 # 开头的行,比如常见的头文件包含(#include)、宏定义(#define)等。

不同种类的预处理命令的处理方式各不相同,比如头文件包含预处理命令(#include)就是把目标头文件的内容读取出来替换掉当前行,宏定义预处理命令(#define)就是把代码中的所有宏名替换为对应的宏值。

以 gcc 编译器为例,假设源文件为 test.c,可以通过下面的命令对源文件进行预处理:

-o 参数用于指定输出文件名,即把预处理结果存放到当前文件夹下的 test.i 文件中。如果不使用 -o 参数,预处理结果将会输出到屏幕上显示。

第 2 步:编译(Compile)

将预处理后的源文件(.i)经过一系列的词法分析、语法分析、语义分析以及优化,加工为当前机器支持的汇编代码文件(.s)。C 语言代码中的语法错误就是在这一步被检查出来的。

对应的命令为:

该命令执行后会在当前目录下生成 test.s 汇编代码文件。注意参数 -S 是大写的。

汇编语言:一种针对底层硬件的低级编程语言,用助记符代表二进制机器指令。汇编代码和具体硬件平台息息相关,不具有移植性。它主要用于嵌入式系统底层开发,不过大部分应用场合都逐步被 C 语言取代,现在用的很少。

第 3 步:汇编(Assemble)

根据汇编语句和机器指令对照表,将上一步得到的汇编代码文件(.s)中的每一条汇编语句都翻译为对应的二进制机器指令,并存放到目标文件(.o)中。虽然目标文件里面存放的都是二进制机器指令,但它不能独立运行,因为它还依赖标准库等其它文件。

对应的命令为:

该命令执行后会在当前目录下生成 test.o 目标文件。

第 4 步:链接(Link)

将项目中的所有目标文件、标准库和指定的第三方库文件链接到一起,生成最终的可执行文件。标准库是必须的,并且会被默认链接。如果代码中调用了某个第三方库,就要通过 -l(指定库名)和 -L(指定库路径)参数指定链接它。如果需要的目标文件或库文件缺失,就会发生链接错误。

本例很简单,就一个目标文件(复杂项目会有多个),也没有调用任何第三方库。对应的命令为:

该命令执行后会在当前目录下生成最终的可执行文件 test.exe。通过 -o 参数可以指定生成的可执行文件的名字,默认为 test.out。Linux 系统上可执行文件的后缀名不要求一定为 .exe,可以为任意值或没有。

经过上面 4 步的依次处理,就可以将源文件转化为最终的可执行文件,当然也可以一步到位。

我们现在用的编译器(比如 gcc 等)不仅仅能进行编译处理,还包含了预处理、汇编和链接功能。在实际开发时,我们都是一键构建,直接将项目中的源文件进行这 4 步处理转化为最终的可执行文件,且不会保留每一步产生的中间文件。

通常我们将第 2 步和第 3 步合在一起统称为编译,最后用一张图总结整个过程。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230221A08SCY00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券