0


程序编译流程

程序编译流程

程序编译流程分为预处理,编译,汇编,链接
一丶预处理
1.预处理阶段会将所有#define删除,并展开所有的宏定义
2.处理所有的条件编译指令,如#if,#ifdef,这些伪指令的引入使得程序员可以通过定义不同的宏来决定编译程序对哪些代码进行处理,预编译程序将根据有关文件,将不必要的代码过滤掉
3.处理#include预编译指令,将被包含的文件插入到该预编译指令的位置(递归进行的,被包含的文件可能还包含其他文件)
4.删除所有注释
5.添加行号和标识,以便于编译器产生调试用的行号信息及用于编译时产生的编译错误或警告能够显示行号
6.保留所有的#pragma编译器指令
二丶编译
将预处理完的文件进行一系列词法分析,语法分析,语义分析及优化后产生相应的汇编文件
三丶汇编
将编译完的汇编代码文件翻译成机器指令,并生成可重定位目标程序的.o文件,该文件为二进制文件,字节编码是机器指令
四丶链接
通过连接器将一个个目标文件连接在一起生成一个完整的可执行程序
1.静态链接:
函数和数据被编译进一个二进制文件,在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函数和数据并把它们和应用程序的其他模块组合起来创建最终的可执行文件。

空间浪费:因为每个可执行程序中对所有需要的目标文件都有一份副本,所以如果多个程序对同一个目标文件都有依赖,会出现同一个目标文件都在内存中存在多个副本。

更新困难:每当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程序。

运行速度快,但是静态链接的优点就是,在可执行程序中已经具备了所有执行程序所需要的任何东西,在执行的时候运行速度快。
2.动态连接:
动态链接的基本思想是把程序按照模块拆分成各个相对独立部分,在程序运行时才将它们链接在一起形成一个完整的程序,而不是像静态链接一样把所有程序模块都链接成一个单独的可执行文件

共享库:就是即使需要每个程序都依赖同一个库,但是该库不会像静态链接那样在内存中存在多份,副本,而是这多个程序在执行时共享同一份副本

更新方便:更新时只需要替换原来的目标文件,而无需将所有的程序再链接一遍,当程序下一次运行时,新版本的目标文件会被自动加载到内存中并链接起来,程序就完成了升级的目标

性能损耗:因为把链接推迟到了程序运行时,所以每次执行程序都需要进行链接,所以性能会有一定损失

例如:某个源文件中的函数可能引用了另一个源文件中定义的某个符号(函数变量或函数调用等),在程序中可能调用了某个库文件中的函数,等等,所有的这些问题,都需要经链接程序的处理方能得到解决
链接程序的主要工作就是将有关的目标文件彼此相连接,也就是将一个文件引用的符号同该符号在另一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体

经过这四个步骤以后,一个完整的可执行程序就产生了
五丶一个栗子

intmain(){fun();}//编译不可通过,提示函数fun()未声明
voidfun();intmain(){fun();}//编译可通过,链接不可通过,提示函数fun()未定义

所以一个函数未声明在编译的过程中被发现
一个函数未定义在链接的时候被发现

标签: c++ c语言

本文转载自: https://blog.csdn.net/weixin_45425093/article/details/120858413
版权归原作者 不摆烂的zzz 所有, 如有侵权,请联系我们删除。

“程序编译流程”的评论:

还没有评论