引言:
在ANSIC中存在两种编译环境
第一种是翻译环境:可以将环境中的源代码转换成能被机器执行的二进制指令;翻译环境即为我们所使用的编译器,可以将test.c文件翻译为test.exe文件
第二种是运行环境:它用于实际代码的执行;一般为操作系统对test.exe文件编译的结果
编译环境
那编译环境是如何将源代码转换为能被机器所执行的二进制指令呢
在翻译环境中,是由编译与链接两个过程构成的,而编译包含预处理、编译、汇编三个过程
在我们在写一个C语言的项目时,可能由多个.c文件的创建,那多个文件是怎样编译的呢?
此时我们继续将编译拆解
答:
- 多个.c文件单独经过编译出编译处理生产对应的目标文件。
- 注:在Windows环境下的目标文件的后缀是 .obj ,Linux环境下目标文件的后缀是 .o
- 多个目标文件和链接库⼀起经过链接器处理生成最终的可执行程序。
- 链接库是指运行时库(它是支持程序运行的基本函数集合)或者第三方库。
预处理
在预处理阶段那种,会将源文件和头文件处理为后缀为i的文件
预处理会主要处理#开始的指令
1.将所有的#define指令删除,展开宏定义
#define a 10 int main (){ int b = a;//当进行预处理时,此语句将变为 int b = 10; 而将#define删除 return 0; }
2.处理所有的条件编译指令,如: #if、#ifdef、#elif、#else、#endif
int main() { int a = 10; int b = 20; int c = 30; int d = a + b;//d ==30 #if 0//如果为1,则正常运行下句 int e = a + c; #endif //相当于注释掉此句 return 0; }
3.处理#include 预编译指令,将包含的头文件的内容插入到该预编译指令的位置。这个4.过程是递归进行的,也就是说被包含的头文件也可能包含其他文件。
5.删除所有的注释
6.添加行号和文件名标识,方便后续编译器生成调试信息等。
7.或保留所有的#pragma的编译器指令,编译器后续会使用。
运行环境
1.程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
2.程序的执行便开始。接着便调用main函数。
3.开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。
4.终止程序。正常终止main函数;也有可能是意外终止。
当我们学到这里,想必你已经学会了机器是怎样执行程序的吧!!!
点个赞走吧!!!