程序编译和链接

    一个源程序到一个可执行程序一般需要经过预编译、编译、汇编和链接四个步骤。当我们使用IDE编写代码的时候,这些过程IDE都会默认的为我们完成。但是了解这些过程都是做什么是很有必要的。

1、预编译

     预编译过程主要处理源文件中以“#”开始的预编译指令。比如“#include”,“#define”等,主要处理规则如下:

  • 将所有的“#define”删除,并且展开所有的宏定义
  • 处理所有的条件预编译指令,比如“#if”,“#ifdef”,“#endif”
  • 处理“#include”指令,将被包含的文件插入到该预编译指令的位置,注意这个过程是递归进行的,也就是说被包含的文件可能还包含其他文件
  • 删除所有的注释“//”、“/**/”
  • 添加行号和文件名标识,以便于编译时编译器产生调试用的行号信息以及用于编译时产生的编译错误或警告时显示的行号
  • 保留所有的#program编译器指令

   进过预编译后,生成的文件不包含任何的宏定义。

2、编译

    编译过程就是把预处理完的文件进过一些列的词法分析、语法分析、语义分析及优化后生成相应的汇编代码文件。

3、汇编

   汇编就是将汇编代码转变成机器可执行的指令,得到目标文件。

4、链接

   链接及时将目标文件进行处理,得到可执行文件。

   下面主要介绍链接的相关知识:

      因为现在的工程越来越大,所以人们将代码按照功能和性质划分,分别形成不同的功能模块,不同的模块之间按照层次结构或者其他结构来组织。

    在上面介绍的前三步中,每一个每一个模块都是单独进行的,不需要其他模块。但是在链接构成中,不同的模块之间就可能需要通信。在前面的步骤中,当需要引用到其他模块的内容的时候,暂时使用一些标记来标识这些引用的地址。

    链接的主要内容就是把各个模块之间相互应用的部分处理好,使各个模块之间能够正确的衔接(这部分会替换前面使用的那些标识地址的内容,该文真正的地址)。

   链接方式分为静态链接和动态链接:

  • 静态链接:静态链接在链接时将输入的目标文件进行合并操作形成可执行文件。

              使用静态链接,链接时将相关的目标文件合并为一个可执行文件。

  • 动态链接:动态链接就是将链接过程推迟到运行时在进行。

        为什么需要动态链接呢?

       因为如果我们使用静态链接,那么对于每一个可执行程序内都会包含与其相关的目标代码,这样就可能会造成浪费内存和磁盘空间,模块更新的困难。

       比如说现在有两个程序program1和program2分别包含program1.o和program2.0两个模块,同时好共用Lib.o模块。在静态编译情况下,因为program1和program2都用到了lib.o米快,所以它们同时在链接输出的可执行文件program1和program2有两个副本。当我们同时运行这两个可执行文件时,Lib.o在磁盘和内存中就有两个副本。这样就会造成内存和磁盘的浪费。

       此外使用静态链接还会造成程序发布和更新的问题。比如program1使用了Lib.o,当Lib.o更新后,program1必须重新进行编译和链接。这样的缺点就是一个很小的模块更新,整个程序都需要从新链接、发布。

    使用动态链接皆可以避免以上两个问题。当然动态链接也有相应的问题,比如模块更新后借口改变了,那么原来的程序就无法运行了。

   所以动态链接和静态链接都有优点和缺点。


你可能感兴趣的:(C++学习,汇编,编译器,磁盘,ide,优化)