编译器的任务是把我们人类通常能够读懂的文本形式的 C 语言文件转化成计算机能明白的目标文件。
1.  预编译
生成的仍然是.c文件
1)把"include"的文件拷贝到要编译的源文件中。
2)用实际值替代"define"的文本。
3)在调用宏的地方进行宏替换。

2.  编译
这个过程是用于生成汇编语言,.asm文件。

3.  生成目标文件
.o文件,包含了以下两项内容

  • 代码:对应着 C 文件中函数的定义
  • 数据:对应着 C 文件中全局变量的定义(对于一个已初始化的全局变量,它的初值也存于目标文件中)。

编译器会留个空白(blank),这个“空白”(我们也称之为“引用”(reference))拥有与之相关联的一个名字,但该名字对应的值还尚未可知。

链接器的任务是连接变量/函数的名字与变量/函数的定义,生成可执行文件。

如果不能连接,就会抛出external error

初始化变量已经提前赋予了某个特定的初值,这些值同时保存于目标文件和可执行文件中。当程序开始运行时,操作系统将这些值拷贝至内存中一块名为数据段(data segment)的区域;对未初始化变量,操作系统假设其初值均为0, 因此没有必要对这些值进行拷贝,操作系统保留一部分全为0内存空间,我们称其为 bss 段(bss segment)。

局部变量的生命周期只存在于程序运行之时,所以链接器无需处理。他们存储在栈或堆中,由于堆和栈在程序运行过程中都会动态地改变大小,通常的处理方式是让栈从一个方向向另一个方向增长,而堆则从另一端增长。

:如果有很多不同的程序都需要做一些相同的操作(例如将输出打印到屏幕上,从硬盘读取文件等),那么所有相关的目标文件集合都统一存放在一个方便访问的地方,这个地方就称为库

静态库(static library),在Windows平台上,静态库的扩展名为 .LIB,可用 .LIB 工具生成。

缺点1:循环依赖。

从静态库中导入文件的粒度:如果某个特定符号的定义是必须的,那么包含该符号定义的整个目标文件(不是整个静态库)被导入。

库的处理顺序。链接器按命令行从左到右的顺序进行处理,只有前一个库处理结束了,才会继续处理下一个库。换句话说,如果后一个库中导入的目标文件依赖于前一个库中的某个符号,那么链接器将无法进行自动关联,导致链接失败。

缺点2:一旦程序完成静态链接后,代码就永久保持不变了,如果万一有人发现并修复了 printf 中的某个bug,那么所有使用了printf的程序都不得不重新链接才能应用上这个修复。

缺点3:所有可执行文件都要存储一份如printf,fopen这类常用函数的拷贝,将占用大量的硬盘空间。

共享库(Shared libraies),其扩展名在 Unix 系统中为 .so,在 Windows 系统中为 .dll,在Mac OS X系统中为 .dylib。

优点1:链接的粒度(the granularity of the link)。

如果程序中只引用了共享库里的某个符号(比如,只使用了 libc.so 库中的 printf),那么整个共享库都将映射到程序地址空间中,之后可自行解决相互引用问题。并且,库内的符号集中保存在一片连续的空间里。

优点2:链接完后改变的代码,在运行时会生效。

优点3:对于共享库,链接器没有必要将所有的符号都关联起来,而是贴上一个“我欠你(IOU)”这样的标签,直到程序真正运行时才对贴有这样标签的内容进行处理。

C++的编译与连接的更多相关文章

  1. gVim/Vim 一键编译、连接、运行 C/C++ 单文件

    用于Gvim 或 Vim 配置文件的一键编译与运行函数(注:需要机器上安装了GCC才行) 本代码只加入了对C/C++的编译与运行,如果要加入其语言的可以参考此代码加入即可 同时,本代码加入了对Wind ...

  2. iOS_02_第一个C语言程序(理解编译、连接、运行)

    一.开发工具的选择 1. 可以用来写代码的工具:记事本.ULtraEdit.Vim.Xcode等. 2. 选择XCode的原因:苹果公司官方提供的开发利器.简化开发的工程.有高亮显示功能. 3. 使用 ...

  3. C编译: 动态连接库 (.so文件)(转摘)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在“纸上谈兵: 算法与数据结构”中,我在每一篇都会有一个C程序,用于实现算法和数据 ...

  4. 如何使用MASM来编译、连接、调试汇编语言

    先声明下,本人绝非大虾,也只是菜鸟一个,写此文的目的只是为了加深我对知识的理解罢了.好,进入正题.我是把masm解压后发在D盘中的一个叫masm的文件里,在masm文件里新建个记事本(记事本功能是很强 ...

  5. C编译: 动态连接库 (.so文件)

    转自:http://www.cnblogs.com/vamei/archive/2013/04/04/2998850.html 在“纸上谈兵: 算法与数据结构”中,我在每一篇都会有一个C程序,用于实现 ...

  6. Keil C51编译及连接技术

    主要介绍Keil C51的预处理方法如宏定义.常用的预处理指令及文件包含指令,C51编译库的选择及代码优化原理,C51与汇编混合编程的方法与实现以及超过64KB空间的地址分页方法的C51实现. 教学目 ...

  7. mtcp的快速编译(连接)

    mtcp的快速编译 http://mos.kaist.edu/guide/config/03_build_mtcp.html 介绍DPDK中使用mtcp的文档 https://dpdksummit.c ...

  8. Makefile之编译运行连接库方法

    LIBS+= -L $$PWD/../HKUnifyCamera_one/Debug -lHKUnifyCamera -luuid -Wl,-rpath=$$PWD/../HKUnifyCamera_ ...

  9. 【Linux下Hadoop-eclipse-plus-3.2.0】编译Hadoop连接eclipse的插件遇见的一系列错误,崩溃的操作

    2019-09-02 23:35:22 前言:首先,我想吐槽下自己,居然花费了4到5个夜晚和中午的时间来做这件事情,直到刚才才顺利解决,我也挺佩服自己的! 我在这个过程中参考其他人的博客,非常感谢他们 ...

随机推荐

  1. 发邮件 文字+ 附件的方法(QQ or 网易 邮箱)

    #coding:utf-8import smtplibfrom email.mime.text import MIMETextfrom email.mime.multipart import MIME ...

  2. [UE4]多播代理

    1. 第一种 DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FReceiveDelegateEvent, FString, Value1, FString, ...

  3. 2018ICPC网络赛(焦作站)K题题解

    一.题目链接 https://nanti.jisuanke.com/t/31720 二.题意 给$N$种船只,第$i$种船的载重量是$V_i$,数量是$2^{C_i}-1$.接下来有$Q$次询问,每次 ...

  4. chapter1 初识Go语言

    1.1 语言简史 1.2 语言特性 I:自动垃圾回收 II:更丰富的内置类型 数组切片(Slice):是一种动态增长的数组. III:函数多返回值 func getName()(firstName, ...

  5. ExtJS的数据模型

    给大家介绍一下ExtJS的组件模型. 常见的Ajax的开发流程: 1.定义URL,metod,params 2.开发后台  接收JSON/XML数据 返回JSON/XML数据 3.前台回调 4.显示到 ...

  6. C#中 ThreadStart和ParameterizedThreadStart区别

    最主要区别: 1.Thread 是启动一个线程,但是没有参数. 2.ParameterThreadStart  线程可以接受一个输入参数 ThreadStart: ThreadStart这个委托定义为 ...

  7. Python预编译语句防止SQL注入

    这个月太忙,最近不太太平,我的愿望是世界和平! ================================== 今天也在找python的预编译,早上写的sql是拼接来构成的.于是找了2篇文章,还 ...

  8. File处理

    package com.cfets.ts.u.shchgateway.util; import java.io.BufferedInputStream; import java.io.Buffered ...

  9. 隐藏bat脚本运行时弹出的黑窗口,以隐藏进程在后台执行.

    1.把这段代码写在前面@echo offif "%1"=="r" goto startif "%1"=="h" goto ...

  10. java8函数式编程(转载)

    1. 概述 1.1 函数式编程简介 我们最常用的面向对象编程(Java)属于命令式编程(Imperative Programming)这种编程范式.常见的编程范式还有逻辑式编程(Logic Progr ...