c++文件从编译到执行

基本步骤

预处理 -> 编译 -> 汇编 -> 链接

预编译:将源文件hello.c和相关的头文件被预编译器编译成一个hello.ii文件(c语言的话.c文件预编译成.i文件)

  • 将#define 删除,展开所有的宏定义
  • 处理条件预编译指令,把包含的文件插入到预编译指令的位置(递归的过程)
  • 删除注释
  • 添加行号,文件名标示
  • 保留#progma编译器指令

编译:把预处理完的文件进行一系列的词法分析、语法分析以及优化后生成相应的汇编代码文件。

汇编:汇编器将汇编代码转为机器可以执行的指令。每个汇编语句都对应一个机器指令。其实就是将.c文件转换为.o目标文件。

链接:得到.out文件。用符号来实现。当一个程序很复杂的时候,我们把每个源代码模块独立的编译,然后按照要求进行“组装”,这个组装的过程就是链接。

编译器

将高级语言翻译成机器语言的工具。

步骤
扫描-> 语法分析 -> 语义分析 -> 源代码优化 -> 代码生成 -> 目标文件优化

链接

定义:当一个程序很复杂的时候,我们把每个源代码模块独立的编译,然后按照要求进行“组装”,这个组装的过程就是链接。

主要内容:将每个模块之间相互引用的部分都处理好,使得各个模块之间能够正确的衔接。

包括: 地址和空间分配、 符号决议、 重定位

例子: 在一个程序模块main.c中要用到另一个模块fun.c的foo()函数,那么在main.c每个用到fun()函数的时候都要知道这个函数的地址。但是因为每个程序都是单独编译的,编译器并不知道foo()的地址,所以编译器暂时用一些符号来替代,暂时将它搁置,等到链接时,再将这些指令的地址修正。使用链接器,可以直接引用其他模块的函数和全局变量,而不需要知道他们的地址。

静态链接与动态链接

静态链接

就是在编译链接时直接将需要的执行代码拷贝到调用处,优点就是在程序发布的时候就不需要的依赖库,也就是不再需要带着库一块发布,程序可以独立执行,但是体积可能会相对大一些。
优点
代码装载速度快,执行速度比动态链接快
只需要保证开发者的计算机有正确的lib文件
缺点
生成可执行文件较大,可能包含相同的代码拷贝

动态链接:

就是在编译的时候不直接拷贝可执行代码,而是通过记录一系列符号和参数,在程序运行或加载时将这些信息传递给操作系统,操作系统负责将需要的动态库加载到内存中,然后程序在运行到指定的代码时,去共享执行内存中已经加载的动态库可执行代码,最终达到运行时连接的目的。优点是多个程序可以共享同一段代码,而不需要在磁盘上存储多个拷贝,缺点是由于是运行时加载,可能会影响程序的前期执行性能。

优点
节省内存并减少页面交换
dll文件与exe文件独立,只需要保证接口不变,更换dll文件对exe无影响,极大地提高可维护性和可拓展性
不同的编译语言可以用同一个dll文件
适用于大规模的软件开发,是的开发过程独立,耦合度小,便于不同开发者和开发组织者之间进行开发和测试。
缺点
如果程序依赖的dll文件不存在,载入动态链接时,程序会终止并给出错误提示,运行时动态链接程序会加载失败
速度慢

区别

  1. 多次调用一个外部的函数(dll文件orlib文件),静态链接可能会有多份拷贝,动态链接只有一份拷贝
  2. 静态链接的话lib文件中的指令会被包含到exe执行文件中,动态链接的话dll文件不必包含在exe执行文件中,exe可以随时动态的卸载和引用这个dll文件。
  3. 静态链接库不能再包含其他动态链接库和静态库,而在动态链接库中可以再包含其他动态链接库和静态库。

猜你喜欢

转载自blog.csdn.net/hgyan25/article/details/79789788