程序运行过程
    1.编译
        a.预处理:删除注释,宏替换,头文件展开,条件编译
        b.编译:词法分析,语法分析,语义分析,符号汇总(生成汇编代码)
        c.汇编:将形成的汇编代码转为二进制代码,形成对应的符号表
    2.链接:合并段表以及符号表的重定位,生成可执行文件
    3.加载:将可执行文件加载到内存中运行

链接:静态链接器
加载:加载器
运行:动态链接器

链接的作用(软件复用):1.分离编译  2.动态绑定,使定义、实现、使用分离
链接器的作用:1.符号解析(定义和引用联系一起)2.重定位:符号定义和内存
地址对应起来,修改所有对符号的引用。

 

预处理阶段头文件的展开是如何寻找到头文件所在位置的?
1.所有头文件首先是-I的开始
2.环境变量C_INCLUDE_PATH、CPLUS_INCLUDE_PATH指定的路径
3.再找默认目录,如/usr/include、/usr/local/include.....

简单来说就是先在当前目录或者上层目录寻找,
找不到就到环境变量下的路径中的默认库函数路径中寻找

编译中的汇编生成的机器代码其实就是段,分为数据段代码段
数据段包含运行程序需要的数据资源;
代码段是程序使用数据的指令。

静态库、动态库

静态库:是将所需目标函数的整个文件拷贝到最终可执行文件中,执行速度快,但是占用消耗的内存大,牺牲空间来提高效率。库文件的变化需要重新编译链接生成新的可执行文件。

动态库(共享库):将目标函数的引用表链接,不是所有目标函数代码,当只有程序运行的时候才会将目标函数的代码拷贝到可执行文件中,执行速度相比于静态库慢,内存占用少,牺牲效率换取空间内存。库变化只需要编译库,不需要重新编译程序。

动态库可以多个应用程序都调用(共享)一个库。