翻译环境和运行环境
在ANSI C的任何一种实现下,存在两种不同的环境:翻译环境和运行环境。
翻译环境:在该环境下,源代码被转换为可执行的机器指令(二进制指令)。
运行环境:代码实际执行的环境。

翻译环境
翻译环境实际上就包含两个过程:编译和链接。源代码文件通过编译器产生目标文件(.obj后缀),目标文件和链接库再通过链接器生成可执行程序(windows环境中为.exe后缀)。

编译
编译又可以分为三个过程:预处理(预编译)、编译和汇编。
预处理(预编译)
预处理也叫预编译,在gcc环境下,源文件经过预处理后会生成.i为后缀的文件。
预处理阶段主要处理那些预编译指令:包括头文件的包含、#define宏定义的文本替换,注释行的删除,条件编译的处理等。有很多,这里简单说几个。
在预处理阶段,我们声明的头文件(比如说<stdio.h>)中的内容会被展开成代码。
也就是说虽然我们实际写的代码只有十几行,但在.i文件中可能会展开成几百行或者上千行。
在预处理阶段我们用#define宏定义的符号会被替换掉,比如下列代码:


在预处理阶段就会被替换成这样:

替换完后该宏MAX就会被移除。
编译
编译阶段会把预处理产生的.i文件进行词法分析、语法分析、语义分析及优化,生成对应的汇编代码。
词法分析
比如说a=3+2;在词法分析阶段会被划分成一系列记号。

语法分析
在语法分析阶段,会生成对应的语法树:

语义分析
由语义分析器来完成语义分析,即对表达式的语法层面分析。这个阶段会报出错误的语法信息。

汇编
在汇编阶段会把编译产生的汇编代码转换为可执行的二进制指令,产生目标文件。
链接
链接是一个复杂的过程,是把所有文件链接在一起生成可执行程序。
链接包括地址和分配内存,符号决议的和重定位等步骤。
链接解决的是一个项目中多个文件、多个模块之间互相调用的问题。






