1、预处理
预处理器负责处理C源程序中的预处理指令,如#include、#define等。预处理器首先读入源代码文件,然后执行指令,将处理结果输出到一个临时文件中,这个临时文件中的内容就是源程序的预处理结果。
预处理指令会被替换成对应的文本或代码,例如,#include指令会将指定的文件包含到当前文件中,#define指令会用宏定义的文本替换程序中出现的标识符。
预处理后的代码通常会比源代码大很多,因为预处理器会把包含的文件展开,宏展开,注释删除等操作。
2、编译
编译器会将预处理后的代码翻译成汇编语言,也就是将高级语言转换成低级语言的过程。编译器会检查语法错误、类型不匹配等错误,如果有错误就会生成错误信息。
编译器的输出通常是汇编代码,这些代码是CPU可以直接执行的指令,但是这些指令通常是以十六进制数的形式表示的,不易读懂。
3、汇编
汇编器会将汇编代码翻译成机器码,也就是将汇编代码转换成CPU可以直接执行的指令。汇编器的输出是一个目标文件,包含了可执行代码和数据,但还不能直接运行。
汇编器的主要工作是将汇编代码转换成机器指令,它会把汇编代码中的符号(如函数名、变量名等)替换成地址,生成目标文件。
4、链接
链接器会将多个目标文件合并成一个可执行文件,它会将所有的函数和数据段放到一个地址空间中,并解析函数之间的调用关系,使得程序可以正确地执行。链接器还会处理一些重定位信息,使得程序可以在内存中正确地运行。
链接器的输出是一个可执行文件,可以在操作系统中直接运行。
C语言程序编译的过程可以简单描述为:源文件 -> 预处理器 -> 编译器 -> 汇编器 -> 链接器 -> 可执行文件。