1.翻译环境和运行环境
翻译环境:在这个环境中,源代码被转换为可执行的机器指令。
运行环境:又称为执行环境,它是用于实际执行代码的。
2.翻译环境
翻译环境由编译和链接两个过程组成,而编译又被分为:预处理(预编译)、编译、汇编三个过程。
一个C语言的项目中可能由多个.c文件一起构成。
- 多个.c文件单独经过编译处理生产出对应的目标文件。(在windows环境中的目标文件的后缀为.obj,Linux环境下目标文件的后缀为.o)
- 多个目标文件和链接库一起经过链接器的处理形成最终的可执行程序。
- 链接库是指运行时的库(它是支持程序运行的基本函数集合)或第三方库。
将编译过程展开成三个过程,如图所示:
2.1预处理(预编译)
在预处理阶段,源文件和头文件会被处理成为.i为后缀的文件。
预处理阶段主要处理那些源文件中#开始的预编译指令,如#include、#define等。处理规则如下:
- 将所有的#define删除,并展开所用的宏定义。
- 处理所有的条件编译指令,如:#if、#ifdef等
- 处理#include预编译指令,将包含的头文件的内容插入到该预编译指令的位置。该过程是递归进行的,即被包含的头文件也可能包含其他文件。
- 删除所有的注释
- 添加行号和文件名标识,方便后续编译器生成调试信息等
- 保留所有的#pragma的编译器指令,编译器后续会使用
2.2编译
编译过程就是将预编译后的文件进行一系列的:词法分析、语法分析、语义分析及优化,生成相应的汇编代码文件。(把C语言代码翻译成汇编代码)
2.2.1词法分析
将源代码程序输入到扫描器中,扫描器的任务就是简单的进行词法分析,把代码中的字符分割成一系列的几号(关键字、标识符、字面量、特殊字符等)
array[index]=(index+4)*(2+6)
对上述代码进行词法分析后会得到16个记号:
2.2.2语法分析
接下来会进行语法分析,语法分析器会扫描产生的记号进行语法分析,从而产生语法树。这些语法树是以表达式为节点的树。如图:
2.2.3语义分析
语义分析是由语义分析器来完成的,即对表达式的语法层面进行分析。编译器所能做的分析是语义的静态分析。静态语义分析通常包括声明和类型的匹配,类型的转换等,该阶段会报告错误的语法信息。如图:
2.3汇编
汇编器是将汇编代码转变成机器可执行的指令,每一个汇编语句几乎都对应一条机器指令。就是根据汇编指令和机器指令的对照表一一的进行翻译,也不做指令优化。
在编译阶段有符号的汇总,而汇编阶段会形成符号表。
2.4链接
链接是将一堆文件链接在一起生成可执行程序。
链接过程主要包括:地址和空间分配,符号决议和重定位等步骤。
链接解决的是一个项目中多文件、多模块之间相互调用的问题。
3.运行环境
- 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存完成。
- 程序的执行便开始,接着调用main函数。
- 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。
- 终止程序。正常终止main函数,也可能是意外终止。