编译与链接
编译环境与运行环境
在ANSI C 的任意一种实现中,存在两个不同的环境:
1.翻译环境,这个环境中的源代码被转换为可执行的机器指令(二进制指令)
2.执行环境,用于实际执行代码。
翻译环境
翻译环境是由编译与链接两大过程组成的 而编译又可以分解为:预处理、编译、汇编三个过程。
源文件经过编译器生成对应的目标文件(.obj) 。
若多个.c文件单独经过编译器,编译处理生成对应的目标文件。
多个目标文件与链接库一起经过链接器生成最终可执行程序。
链接库是指运行库或者第三方库
预处理
预处理阶段,源文件和头文件会被处理成.i为后缀的文件
这个阶段,主要处理那些原文件中#开始的预编译指令 规则如下:
1 将所有的 #define 删除,并展开所有的宏定义。
2 处理所有的条件编译指令,如#if #iedef #elif
3 处理 #include 预编译指令,将包含的头文件的内容插入到该预编译指令的位置,这个过程是递归进行的,也可能包含其他文件
4 删除所有注释
5 添加行号与文件名标识,方便后续编译器生成调试信息等
6 或保留所有的 #pragma 的编译器指令,编译器后续会使用。
编译
词法分析
它的任务是读取源代码,并将其分解成一系列的词法单元(tokens)。词法单元是源代码中的基本语法元素,例如关键字、标识符、常数、运算符和分隔符等。以下是词法分析的一些关键点:
- 将源代码字符串转换成词法单元序列。
- 忽略源代码中的空白、注释等无关紧要的部分。
- 检测并报告词法错误,如非法字符或词法格式错误。
语法分析
语法分析的主要任务是验证程序的语法结构是否正确,并根据某种形式文法(通常是上下文无关文法)将词法分析阶段产生的词法单元(tokens)组织成一棵抽象语法树(Abstract Syntax Tree, AST)。
语义分析
它不仅检查源代码是否符合语法规则,还确保程序的行为符合开发者的意图。通过语义分析,编译器能够在程序运行之前发现许多潜在的错误,从而提高程序的质量和可靠性。(语义的静态分析:声明和类型的匹配 )
汇编
汇编器是将汇编代码转变为机器可执行指令,每一个汇编语句几乎都对应一条机器指令。就是根据汇编指令和机器指令的对照表一一进行翻译,也不做优化指令。
运行环境
程序执行的过程:
1. 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序 的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
2. 程序的执行便开始。接着便调用main函数。
3. 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回 地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程 一直保留他们的值。
4. 终止程序。正常终止main函数;也有可能是意外终止。