C语言 编译过程
什么是编译
编译是将源代码转换为目标代码的过程。它是通过编译器完成的。编译器会检查源代码的语法或结构错误,并在源代码无错误时生成目标代码。
编译过程将输入的源代码转换为目标代码或机器代码。编译过程可以分为四个步骤,即预处理、编译、汇编和链接。
预处理器将源代码作为输入,并将源代码中的所有注释删除。预处理器获取预处理指令并进行解释。例如,如果程序中使用了<stdio.h>这个指令,预处理器会解释该指令,并将该指令替换为文件的内容。
下面是我们的程序在变成可执行形式之前经过的阶段:
- 预处理器
- 编译器
- 汇编器
- 链接器
预处理器
源代码是在文本编辑器中编写的代码,源代码文件的扩展名为”.c”。这个源代码首先传递给预处理器,然后预处理器会扩展这段代码。在代码扩展之后,扩展后的代码会传递给编译器。
编译器
预处理器扩展的代码会传递给编译器。编译器将这段代码转换成汇编代码。或者我们可以说C编译器将预处理过的代码转换成汇编代码。
汇编器
汇编代码通过汇编器转换成目标代码。汇编器生成的目标文件的名称与源文件相同。在DOS中,目标文件的扩展名是”.obj”,在UNIX中,扩展名是”o”。如果源文件的名称为 ‘hello.c’ ,那么目标文件的名称将是’hello.obj’。
链接器
主要上,所有用C语言编写的程序都使用库函数。这些库函数是预编译的,库文件的目标代码以’.lib’(或’.a’)的扩展名存储。链接器的主要工作是将库文件的目标代码与我们程序的目标代码组合起来。有时候我们的程序会引用其他文件中定义的函数,这时链接器发挥非常重要的作用。它将这些文件的目标代码与我们的程序链接起来。因此,我们可以得出结论,链接器的工作是将我们程序的目标代码与库文件和其他文件的目标代码链接在一起。链接器的输出是可执行文件。可执行文件的名称与源文件相同,只是扩展名不同。在DOS中,可执行文件的扩展名是’.exe’,在UNIX中,可执行文件可以被命名为’a.out’。例如,如果我们在程序中使用printf()函数,链接器会将其相关的代码添加到输出文件中。
通过一个例子来理解。
hello.c
#include
int main()
{
printf("Hello javaTpoint");
return 0;
}
现在,我们将为上面的程序创建一个流程图:
在上面的流程图中,执行程序的步骤如下:
- 首先,输入文件,即 hello.c, 被传递给预处理器,预处理器将源代码转换为扩展源代码。扩展源代码的扩展名应为 hello.i。
- 扩展源代码被传递给编译器,编译器将此扩展源代码转换为汇编代码。汇编代码的扩展名应为 hello.s。
- 然后,汇编代码被发送到汇编器,汇编器将汇编代码转换为目标代码。
- 创建目标代码后,链接器将创建可执行文件。加载器将加载可执行文件以便执行。