一个程序从开始运行到结束的完整过程
源程序是指未经编译的,按照一定的程序设计语言规范书写的,人类可读的文本文件,源程序就是所写好的代码。
可执行程序,即常说的.exe程序,可以执行程序,完成计算机功能。在C语言中,.c文件就是所谓的源文件。
源程序到可执行程序的过程。在这个过程中,会发生如下的变化:
.c文件生成.obj文件的过程,称为编译,.obj文件生成到.exe文件的过程,称为链接。
.obj文件就是一个是程序编译生成的二进制文件,当.exe文件生成以后.obj文件就会被删除。
事实上,.c文件生成.exe文件的过程总共是经历了预处理,编译,汇编,链接,这四个过程。
1、预处理
为了接下来能够解释的更加清楚,使用linux平台下的gcc编译器解释。
先书写一个非常简单的程序来介绍:
test.c
1 #include<stdio.h> 2 3 int main() 4 { 5 printf("hello"); 6 7 return 0; 8 }
直接编译得到:
第一步发生的是预编译,使用-E指令会使程序只进行到预编译指令。经过预编译指令后的会生成一个.i文件。
在预编译的过程中,主要处理源代码中的预处理指令,引入头文件,去除注释,处理所有的条件编译指令,宏的替换,添加行号,保留所有的编译器指令。
当进行预编译以后的文件中将不再存在宏,所有的宏都已经被替代。当想要判断宏是否正确或者头文件包含是否正确时,也可以通过预编译来查看。
2、编译
在预处理结束后,进行的是编译。编译过程所进行的是对预处理后的文件进行语法分析,词法分析,语义分析,符号汇总,然后生成汇编代码。
3、汇编
汇编过程将汇编代码转成二进制文件,二进制文件就可以让机器来读取。每一条汇编语句都会产生一句机器语言。
在这里最终会生成一个重定位目标文件 .o文件,类似windows下的.obj文件。这里生成的目标文件里面就是二进制文件。另外,在这里会形成符号表,给这些符号会分配虚拟地址。
4、链接
由汇编程序生成的目标文件并不能立即就被执行,其中可能还有许多没有解决的问题。例如,某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数等等。所有这些问题,都需要经链接程序的处理方能得以解决。链接程序的主要工作就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。
链接分为静态链接和动态链接:
静态链接:后缀是.a,主要在编译的时候将库文件里面代码搬迁到可执行的文件中;
动态链接:后缀是.so,主要在执行的时候需要转换到库文件代码执行;
两种链接的优缺点:
(1)静态的链接产生的可执行的文件体积比较的大;而动态链接的可执行文件的体积比较小;
(2)动态的链接的编译的效率比较的高;
(3)静态链接的可执行的文件执行的效率高
(4)静态链接的可执行的文件的“布局”比较好一点;