C 语言的编译过程

C 语言的编译过程

❮ 上一节

下一节 ❯

C 语言的编译过程

C 是一种编译型语言。与解释型语言相比,编译型语言提供更快的执行性能。编译 C 程序可以使用不同的编译器产品,例如 GCC、Clang、MSVC 等。本章将解释使用 GCC 编译器编译 C 程序时的后台运行情况。

编译 C 程序

由 1 和 0 位组成的二进制指令序列称为机器码。高级编程语言(例如 C、C++、Java 等)包含的关键字更接近人类语言(例如英语)。因此,用 C(或任何其他高级语言)编写的程序需要转换为等效的机器码。此过程称为编译。

请注意,机器码特定于硬件架构和操作系统。换句话说,在 Windows 操作系统的计算机上编译的某个 C 程序的机器码与在 Linux 操作系统的计算机上不兼容。因此,我们必须使用适合目标操作系统的编译器。

C 编译过程步骤

在本教程中,我们将使用 gcc(GNU 编译器集合)。 GNU 项目是由 Richard Stallman 发起的自由软件项目,旨在让开发者免费使用强大的工具。

gcc 编译器支持多种编程语言,包括 C 语言。为了使用它,我们需要安装与目标计算机兼容的版本。

编译过程分为四个不同的步骤 -

预处理

编译

汇编

链接

下图展示了编译过程。

示例

为了理解此过程,我们来看一下以下 C 语言源代码 (main.c) -

#include

int main(){

/* 我的第一个 C 语言程序 */

printf("Hello World!

");

return 0;

}

输出

运行代码并检查其输出 −

Hello World!

".c"是文件扩展名,通常表示该文件是用 C 语言编写的。第一行是预处理器指令 #include,指示编译器包含 stdio.h 头文件。/* 和 */ 中的文本是注释,用于文档编写。

该程序的入口点是 main() 函数。这意味着程序将从执行该函数块内的语句开始。此处,在给定的程序代码中,只有两条语句:一条在终端上打印"Hello World"语句,另一条语句指示程序在正确退出或结束时"返回 0"。因此,一旦我们编译完成,运行该程序时,我们只会看到"Hello World"这句话。

C 语言编译过程内部包含哪些内容?

为了使"main.c"代码可执行,我们需要输入命令"gcc main.c",编译过程将执行其包含的所有四个步骤。

步骤 1:预处理

预处理器执行以下操作:

它会删除源文件中的所有注释。

它会包含头文件的代码,头文件是一个扩展名为 .h 的文件,其中包含 C 函数声明和宏定义。

它会将所有宏(已命名的代码片段)替换为其值。

此步骤的输出将存储在一个文件中,其中包含扩展名为".i",因此它将位于"main.i"中。

为了在此步骤后立即停止编译,我们可以在源文件上使用 gcc 命令的"-E"选项,然后按 Enter 键。

gcc -E main.c

步骤 2:编译

编译器从预处理文件生成 IR 代码(中间表示),因此这将生成一个".s"文件。话虽如此,其他编译器可能会在此编译步骤生成汇编代码。

我们可以在此步骤后使用 gcc 命令中的"-S"选项停止,然后按 Enter。

gcc -S main.c

main.s 文件应该如下所示 -

.file "helloworld.c"

.text

.def __main; .scl 2; .type 32; .endef

.section .rdata,"dr"

.LC0:

.ascii "Hello, World! \0"

.text

.globl main

.def main; .scl 2; .type 32; .endef

.seh_proc main

main:

pushq %rbp

.seh_pushreg %rbp

movq %rsp, %rbp

.seh_setframe %rbp, 0

subq $32, %rsp

.seh_stackalloc 32

.seh_endprologue

call __main

leaq .LC0(%rip), %rcx

call puts

movl $0, %eax

addq $32, %rsp

popq %rbp

ret

.seh_endproc

.ident "GCC: (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0"

.def puts; .scl 2; .type 32; .endef

步骤 3:汇编

汇编器获取 IR 代码并将其转换为目标代码,即机器语言代码(即二进制)。这将生成一个以".o"结尾的文件。

我们可以在 gcc 命令中使用选项"-c"并按 Enter 键来停止此步骤后的编译过程。

请注意,"main.o"文件不是文本文件,因此使用文本编辑器打开此文件时无法读取其内容。

步骤 4:链接

链接器会创建最终的二进制可执行文件。它将所有源文件的目标代码链接在一起。链接器知道在静态库或动态库中查找函数定义的位置。

静态库是链接器将所有用到的库函数复制到可执行文件的结果。动态库中的代码不会被完整复制,只有库的名称会被放入二进制文件中。

默认情况下,在第四步也是最后一步之后,即输入完整的"gcc main.c"命令而不使用任何选项时,编译器将创建一个名为"main.out"(在 Windows 系统中为"main.exe")的可执行程序,我们可以从命令行运行该程序。

我们也可以选择创建具有所需名称的可执行程序,方法是在 gcc 命令中添加"-o"选项,该选项位于我们正在编译的文件名之后。

gcc main.c -o hello.out

因此,如果您没有使用"-o""选项,那么现在我们可以输入"./hello.out"或者"./hello" 执行编译后的代码。输出将是"Hello World",随后会再次出现 shell 提示符。

❮ 上一节

下一节 ❯

相关文章

steam怎么玩使命召唤21cod21 详细下载教程+下载慢解决方法
微信备份又升级:外部存储 + 自动化,还是谈不上「好用」吗
暗的成语
365信誉线上

暗的成语

🕒 07-04 👁️ 5936