我们用C语言编写一个源代码,然后在编译器编译运行出结果就可以了,但是很少去关注其从开始执行编译到最后结果运行的具体过程,知其然不知其所以然,最近花了一点时间了解了一下具体过程,个人感觉,对自己学习编程是有帮助的。
首先,我们编写的源代码是一种高级语言,我们自己能看懂( 假装能够看懂 ),并不能被CPU直接识别,所以从编写源代码开始到cpu直接运行的可执行文件,这个过程要经历预处理、编译、汇编、链接几个过程;
1、预处理:预处理器在源代码上执行一些文本操作主要做这样几个工作,
1)删除所有的#define,并展开所有的宏定义
2)处理所有的条件预编译指令#if #ifdef #elif #else #endif
3)处理#include预编译指令,将被包含的文件插入到该预编译指令的位置
4)删除所有的注释 /* */ // 等
5)添加行号和文件标识,
6)保留所有的#pragma编译器指令;其作用是设定编译器的状态或者指示编译器完成一些特定的状态。
2、编译compilation
编译就是把预处理后的文件进行语法,语义,词法分析及优化后生成对应的汇编代码
3、汇编assembly
汇编就是使用汇编器将汇编代码转化成机器可以识别执行的机器代码(二进制文件,目标代码),目标代码是机器指令的初步形式,用于实现程序的语句,存放这些目标代码的文件就是目标文件,扩展名为.o或者.obj,目标文件包括机器代码和代码运行时所使用的数据,如重定位信息,如用于链接或调试的程序符号(变量和函数的名字),另外还包括其他调试信息。
4、链接linking
链接器的主要工作就是将各个模块之间的引用部分处理好,使得各个模块之间能够正确衔接,
通过链接器链接程序运行时所需要的目标文件,以及相应的库文件,最后生成可执行文件,
其中链接分为动态链接和静态链接,其中,动态链接在程序启动后才动态加载目标文件,优点是即使每个程序都依赖同一个库,但是该库不会像静态链接那样在内存中存在多份备份,而是这多个程序在执行时共享同一份副本,还有就是更新比较方便;静态链接是将是将库的内容直接加入到可执行程序中,此时程序中已经具备了所有执行程序所具有的任何东西,在执行时运行速度更快,,但是浪费空间,更新比较困难;