C语言——编译全过程的那些事
- 一、C语言的编译过程
- 二、编译的详细过程
- 2.1预编译过程
- 2.2编译过程
- 2.3 汇编过程
- 2.4链接过程
- 三、编译全过程
一、C语言的编译过程
1.C语言的编译过程通常可以分为两个大的部分,编译和链接。
2.在ANSI C的任何一种实现中,存在两个不同的环境。第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。第2种是执行环境,它用于实际执行代码。
二、编译的详细过程
#include<stdio.h>
//预编译过程
#define N 3
int main()
{
printf("%d",N);
printf("hello world\n");
return 0;
}
我们以上述代码为例讲解C语言的编译过程,编译过程优可以分为3个具体的部分,分别是,预处理(Prepressing),编译(Compilation),汇编(Assembly)。
2.1预编译过程
首先是源代码文件test.c和相关的头文件,如stdio.h等被预编译器预编译成一个.i文件。我们在gcc环境下进行演示。
第一步预编译的过程相当于如下命令(-E表示只进行预编译)。
gcc -E test.c -o test.i
预编译输出的test.i的文件的部分图示如下:
预编译过程主要处理那些源代码文件中的以“#”开始的预编译指令。比如“#include”、“#define”等,主要处理规则如下:
1、将所有的“#define”删除,并且展开所有的宏定义。
2、处理所有条件预编译指令,比如“#if”、“#ifdef”、“#elif”、“#else”、“#endif”。
3.处理所有的“#include"预编译指令,将被包含的文件插入到该预编译指令的位置。注意这个过程是递归的,也就是说被包含的文件也可能包含着其他的文件。
4.删除所有的注释"//"和 “/* */”。
5.添加行号和文件名标识。
6.保留所有的#pragma编译器指令,因为编译器需要使用它们。
2.2编译过程
编译过程就是把预编译过程处理产生的文件进行一系列的词法分析,语法分析,词义分析
以及优化后产生的相应的汇编代码文件。这个过程往往是我们所说的程序构建的核心部分。
gcc -S test.c -o test.s
2.3 汇编过程
汇编器是将汇编代码转换成机器可以识别的指令,每一条汇编语句几乎都对应着一条机器指令,所以汇编器的汇编过程相对于编译器的编译过程来说比较简单。它没有复杂的语义,也没有复杂的语法,也不需要做指令优化。只是根据汇编指令与机器指令的对照表进行一一翻译即可。
gcc -o test.s -o test.o
2.4链接过程
链接过程主要包括:
1.合并段表
2.符号表的合并和符号表的重定位