预处理即对源码进行编译前处理
语句前为"#"的语句就是在预处理期间作用的
如#include会在此位置帖上文件的内容,#define则会替换字串的内容
编译是将源文件处理成目标文件的过程,目标文件并不是可执行的代码,它包含有许多位置代码,如某些函数在可执行文件的实际位置
如编译出来的目标文件有类似的位息:
main: 233
fun1: 300
fun2: 545
fun3: 700
链接则是将许多目标文件合并处理成可执行文件
如上例中
main和fun1在1.obj中
fun2和fun3在2.obj中
这样在第一个文件中main函数里可以调用fun2,并可以通过编译,而不用定义
在链接时,链接器统计所有obj里的这种位置信息
然后将1.obj中引用fun2中的内容替换成545
这样,两个obj中的函数等信息可以互相调用
compile和link是大多数语言从原代码生成可执行程序的两个步骤。
之所有有这两个步骤因为几乎任何一个程序都不是用一个原文件写出来的。compile是先针对单独原文件进行处理。link是把compile处理的结果组合成一个完整的可执行文件。
其实C/C++完全也可以一步成型,不需要compile和link两个步骤,但是那样的后果就是:一,每次生成可执行程序,必须翻译全部源代码;二,C语言的执行库(printf, scanf这些)必须都以源代码形式存在。这怎么样也说不过去吧。
另外头文件不属于compile和link过程,头文件是预编译过程的文件。
C/C++语言的完整编译过程是
一、预编译
处理#define #if #include这类#开头的语句,这些称为预编译指令。这个过程中会把.h文件和.c/.cpp文件组合成最终交给compile过程的原文件。这个原文件是不包含任何#开头的语句的。所有#define定义的宏也会被替换。
二、编译
把上面那个原文件编译成.o或者VC里是.obj文件。这个文件保存了机器码化的函数、函数的描述、全局变量的描述、乃至段的描述等等。
三、连接
把可执行程序需要的所有的编译过程产生的.o或者.obj文件组合到一起。(这里也包括.lib文件,.lib文件件本质上就是打包的.obj文件集合)。另外连接过程还会组合一些其他数据,比如资源、可执行文件头等等。