当前位置: 首页 > 编程日记 > 正文

程序的编译和链接过程

一.虚拟机、linux简介
简单介绍一下虚拟机还有就是各种操作系统,比如centos,Ubuntu
操作系统:linux(centos、Ubuntu、redhat),Android,Windows(xp、win8、win10)
进程,多个程序,分时技术,并行技术
一次打开多个程序,我们在只有一个cpu,如何让这些程序进行执行呢,看起来好像是在同时进行的,实际上是一个程序执行了一点点时间,然后保存执行的一些信息,接下来回来再次执行,这样就达到了看上去是多个程序在同时执行的效果
操作系统的作用:控制程序的执行,管理系统的资源

二.程序的编译链接过程

2.1首先看一下预处理的指令


关于上面的预处理指令,大家可以自己测试一下

(测试例子)(注意是两行)
ANSI 标准 C 定义的几个宏如下,大家可以简单的了解一下
__LINE__ 表示正在编译的文件的行号
__FILE__ 表示正在编译的文件的名字
__DATE__ 表示编译时刻的日期字符串,例如: "25 Dec 2007"
__TIME__ 表示编译时刻的时间字符串,例如: "12:30:55"
__STDC__ 判断该文件是不是定义成标准 C 程序

2.2宏定义
编译器在预处理的时候,就会把宏定义的数据替换成它的元身,这里我们必须了解什么是宏,宏的主要的用法
2.2.1 定义宏常量
#define PI 3.14159265358979323846264338327
比如我们经常使用的一个变量,如果这个变量的数值改变了之后,我们不需要再文件里面一个一个找,而是只需要把宏改变就可以了
#define ERROR_TEST -1
比如我们在test文件中,一些代码的地方需要使用return -1,或者是exit(-1)
然后有很多类型的错误返回,如果每次返回的是-1,-2,-3之类的,一会就把自己给绕晕了
2.2.2定义字符串常量
#define PATH "c/file/linux"
这个一般用在表示文件的路径的情况下有很多
(大家下去看一下,如果是一行写不下怎么办呢,就是比如一行太长了怎么办)
2.2.3 定义注释
#define ZZ //
因为在程序编译的时候,注释是先于宏处理的
2.2.4 定义表达式(宏函数)
#define MUL(x) x*x
纯文本替换
测试用例
MUL(5);MUL(1+2); --- 加上括号MUL((x)*(x))
MUL(5*3)*MUL(5*3) --- 大括号???不要吝啬括号
2.2.5 空格
#define MUL (x) ((x)*(x))
比如上面的宏函数,我们要是定义成下面的这个样子又是什么样的呢
2.2.6#undef
撤销宏定义
比如
#define PI 3.14159265358979323846264338327
...
...
...
#undef PI此时PI不在有效了
2.2.7定义宏函数补充
比如下面的程序
#define PRINTF printf("测试");

这个时候我们可以编写 一个if esle语句
if(0)
PRINTF;
else
printf("haha\n");

宏函数比普通函数的一些特性在哪里
(1)普通的函数需要建立栈帧,开销较大,宏函数在效率上面更胜一筹
(2)函数中的参数必须使用特定的类型,换句话说,宏函数对参数是不进行类型检查的,宏函数是不类型限制的

宏函数的缺点
宏函数每次是进行的代码的替换,有时候可能会增加代码的长度,使维护起来非常的复杂
宏函数的参数不能是一个类型

2.3. 条件编译
第一种形式:
#ifdef 标识符
程序段 1
#else
程序段 2
#endif
它的功能是,如果标识符已被 #define 命令定义过则对程序段 1 进行编译;否则对程序段 2
进行编译。

第二种形式
#ifndef
标识符程序段 1
#else
程序段 2
#endif

第三种形式
#if 常量表达式
程序段 1
#else
程序段 2
#endif


2.4. 文件包含
文件包含是预处理的一个重要功能,它可用来把多个源文件连接成一个源文件进行编译,结果将生成一个目标文件。C语言提供#include 命令来实现文件包含的操作,它实际是宏替换的延伸,有两种格式:
#include<filename>
#include"filename"
2.5.#pragma 预处理
自己上网调研,写博客,写测试用例
#pragma once
#pragma warning
#pragma pack--这个是张晨亮学长给你们讲过的,设置内置内存对齐数


2.6详解程序编译和链接过程
程序的编译和链接的过程
我们在linux下使用gcc编译器直接对程序进行编译,比如使用gcc test.c,然后就会生成一个程序叫做test.out
但是上面的看似简单的过程实际上是经历了四个阶段
预处理,编译,汇编,连接
每个过程都有自己要完成的任务




记住一些操作,ESc对应的是iso,

2.6.1. 预处理
通过预处理生成一个.i的文件,使用的指令是
gcc -E test.c -o test.i
(G)
预处理过程主要处理的是1. 以#开始的预处理指令(保留#pragma)2.删除所有的注释3.添加文件名和行号,具体的过程如下
  • 将所有的#define删除,展开所有的宏定义
  • 处理所有的条件预编译指令,比如#if,#ifdef....
  • 处理所有的#include预编译指令,将所有被包含的文件包含至本文件中来
  • 删除所有的注释,//和/* */等
  • 保留所有的#pragma预处理指令,因为下面还要用到它
2.6.2.编译
gcc -S test.i -o test.s
作用:将预处理后的文件,进行一系列的词法分析,语法分析,语义分析及优化后生成相应的汇编代码(这里我们就可以写一个错误的语句来示范一下)
2.6.3. 汇编
gcc -c test.s -o test.o
将汇编代码解释成编译器可以执行的二进制代码
:%!xxd
2.6.4. 链接
gcc -o test.o test
这里我们有一个疑问,不是说上面的汇编已经将程序变成了二进制代码了,为什么还要链接呢,链接是咋链接呢,和谁恋呢,恋啥呢
讲述一下编写程序发展的历史,一开始是程序员是机器码,就是一个一个的纸条上面的01代码,但是这种代码太晦涩难懂了,于是出现了汇编语言,汇编语言出现之后的一个很大的问题就是,代码的数量大大的增加了,这就使得维护代码起来比较复杂,于是人们为了便于维护,又想起把代码分成不同的模块,每个模块负责不同的作用,就比如一个头文件是专门处理图片的,一个头文件是专门处理音频,这样就产生了不同的模块,这些模块之间存在着不同的调用的过程,然后就是要把不同的分开的模块组装起来就是链接的过程。
人们将每个源代码模块独立的编译,然后将编译后的模块按照他们的需求组装起来就是链接的过程。
发给大家一篇PDF《静态库和动态库》


推荐书目:《程序员的自我修养--链接、装载与库》
《C语言深度剖析》


























相关文章:

Nosql网络阅读

#1 Node.jsmongodb 开源项目 https://github.com/DoubleSpout/wujb  作者博客:http://snoopyxdy.blog.163.com/blog/static/60117440201261844125973/ #1 关系数据库还是NoSQL数据库 NoSQL的分类 NoSQL仅仅是一个概念&#xff0c;NoSQL数据库根据数据的存储模型和特点分为很多…

python 文案自动生成_Python自动化测试如何自动生成测试用例?

原文作者&#xff1a;陈安妮annie1原出处&#xff1a;简书上文内容不用于商业目的&#xff0c;如涉及知识产权问题&#xff0c;请权利人联系博为峰&#xff0c;我们将立即处理。传统的测试用例需要测试或者开发人员将用户的操作用代码表示出来&#xff0c;通过断言判断是否和预…

Linux下图解minicom安装

Linux下图解minicom安装 minicom是一个串口通信工具&#xff0c;就像Windows下的HyperTerminal。可用来与串口设备通信&#xff0c;如调试交换机和Modem等。它的Ubuntu软件包的名称就叫minicom&#xff0c;用apt-get install minicom即可安装。全文见附件pdf

【C#技术】一篇文章搞掂:Infragistics组件库

工具栏 // 按钮不可按 tool.SharedProps.Enabled false; Grid // Grid中记录时间 // 建议SQL Server中使用字符字段&#xff08;没有深入测试&#xff0c;只是字符字段可行&#xff09;&#xff0c;然后设置Grid的属性中&#xff0c;列的Style属性为Time或TimeWithSpin// 使用…

移动端开发小结

1. viewport viewport&#xff1a;除去所有工具栏、状态栏、滚动条等之后用于查看网页的区域&#xff0c;打个比方&#xff0c;现在有一张报纸摆在你面前&#xff0c;但是这张报纸被一本书压住了&#xff0c;所以你只能看到报纸的一部分&#xff0c;这部分可以查看到的区域就是…

vim编辑文章后不能修改

我们在使用vim打开一个文件的时候&#xff0c;经常会弹出下面的界面 为什么会出现这个界面呢 用vim编辑文件(如这里的test.txt)时,系统会自动产生一个文件叫.test.txt.swp.如果正常退出,此文件会被自动删去.如果上次非正常退出,如果再编辑它,系统会首先查.test.txt.swp 是否存…

echart x轴标签偏移_移动端H5页面滑动手势X轴实例

话不多少&#xff0c;上代码。let touchX 0 // 默认初始值// 两行注释伪代码&#xff0c;绑定 touchstart 与 touchend 事件// dom.addEvenetListener(touchstart, touchStart)// dom.addEvenetListener(touchend, touchEnd)function touchStart(e) { // 手指触碰时候&#xf…

读书笔记(2) OpenLayers中的图层

OpenLayers有多个不同的图层类&#xff0c;每一个都可以连接到不同的地图服务器。例如通过Layer.WMS类可以连接到WMS地图服务器&#xff0c;通过Layer.Google类可以连接到谷歌地图服务器。OpenLayers中的每个图层都是独立的&#xff0c;对一个的操作不会影响到另外一个。 不管地…

自定义WPF窗体形状

介绍 你好WPF爱好者。 随着WPF等统一API语言的发明&#xff0c;丰富用户界面变得非常容易。 创建丰富的用户界面只是一个想法。 您需要拥有的是创造性思维和最新技术融合。 WPF和Expression Blend在制作丰富的UI应用程序&#xff0c;清晰的图形和非常好的动画方面非常有用。 背…

与jQuery的感情碰撞——由浅入深学jQuery

原来的时候自己看过jQuery&#xff0c;但是对于什么是jQuery&#xff0c;除了知道jQuery是一种javascript类库外&#xff0c;除了会用几个网页特效外&#xff0c;其他的我这真的是不知道啊。眼看自己就要找工作了&#xff0c;所以自己需要好好学习一下&#xff0c;系统的了解一…

线程互斥和同步-- 互斥锁

一. 线程分离我们一般创建的线程是可结合的&#xff0c;这个时候如果我们调用pthread_jion()去等待的话&#xff0c;这种等待的方式是阻塞式等待&#xff0c;如果主线程一直等待&#xff0c;主线程就无法做其他的事情了&#xff0c;所以应该使用线程分离&#xff0c;让子线程由…

calipso是什么意思_眰恦是什么意思?

展开全部眰恦作为一个不常见到的词&#xff0c;其实出自一本同名小说的书名。眰恦读作zh shng &#xff0c;在书中62616964757a686964616fe59b9ee7ad9431333433656665的意思就是&#xff0c;目光所至&#xff0c;心之所向&#xff0c;皆是你。眰&#xff0c;单字意思是视&#…

一个mongosee例子

var express require(express),mongoose require(mongoose); //引入mongoose模块 //连接mongodb数据库 nodejs为数据库名称 mongoose.connect(mongodb://localhost/nodejs);//获取Schema 以及 ObjectId 对象 var Schema mongoose.Schema,ObjectId Schema.ObjectId;//创建一…

mongoDB入门

**使用了不存在的对象&#xff0c;即创建该对象use db 使用db数据库 show dbs 查看当前服务器中写在磁盘上的数据库 show tables 查看数据库中的collection db 查看当前使用的数据库1.增删改查&#xff1a; 增&#xff1a;db.collection.insert({数据}) 自动生成 _id : ObjectI…

哈希--直接定值法和除留取余法

1. 哈希是一种算法&#xff0c;哈希表是用哈希算法构造出来的一种数据结构2. 哈希算方法的几种方法直接定值法 这里有一个例题&#xff0c;就是我们想判断某一字符串中&#xff0c;某一个字符出现的个数&#xff0c;我们可以使用哈希的思想&#xff0c;就是可以遍历一遍字符串&…

两条波浪线符号_四年级数学上册第二单元“线的认识”作业单(附带答案)

“线的认识”作业单一、线段、射线和直线。1.“线段、射线和直线”之间的联系与区别。名称形状长度端点关系2.表示方法&#xff1a;分别画出一条线段、射线和直线&#xff0c;并用字母进行表示。3.概念&#xff1a; (1) (2) (3) 二、相交与垂直1.概念&#xff1a;(1) (2)表示方…

CTime类小结1

参考&#xff1a;http://www.cnblogs.com/chuncn/archive/2009/03/12/1409261.html CTime类1&#xff0e;构造和初始化CTime类对象CTime类有下列构造函数&#xff1a;CTime&#xff08; &#xff09;;CTime&#xff08; const CTime& timeSrc &#xff09;;CTime&#xff0…

oracle数据库动态与静态注册

oracle数据库动态与静态注册 动态注册:1.服务名来自于参数文件中的service_names或者是db_name与db_domain的组合;2.实例名来自与参数文件中的instance_name;3.动态注册不需要listener.ora监听文件支持;4.实例状态为READY或BLOCKED;静态注册:1.服务名来自于监听文件中的GLOBAL_…

如何实现流畅观影体验?视频类应用内存和CPU大调查

如果把手机内存和CPU想象成固定面积的田地&#xff0c;单个应用对内存和CPU的占用则可比喻为个人的一亩三分地儿。当应用内存和CPU占用过高时&#xff0c;便过多占用了整个田地资源&#xff0c;挤压了邻家应用的面积&#xff0c;那么手机能够同时运行的应用的数量就会相应减少。…

dmol3给定关键字不在字典中_python中的数据结构与算法(2):字典与集合

1. 字典是什么字典是便于信息检索的一种数据结构&#xff0c;鉴于信息检索在程序中无处不在&#xff0c;字典的使用场景也非常广泛&#xff0c;包括许多 python 内部机制的实现&#xff0c;也依赖字典结构&#xff0c;比如命名空间的管理等。检索一般是根据关键字查找与它关联的…

HTTP项目1.0 -- HTTP协议基础知识

一. HTTP之URL篇首先来看一下&#xff0c;我们一般在上网的时候&#xff0c;地址栏中经常会显示的信息&#xff0c;这里就举一些简单的例子https://www.baidu.comhttps://113.2.7.58.25/a/b/c.html从上面的简单的例子我们把url分成了以后的几个部分&#xff0c;请看下图第一个协…

SQL Server 远程无法连接

1. 查看默认1433端口是否已经开启。转载于:https://www.cnblogs.com/jiajinyi/archive/2013/05/21/3091091.html

WCF客户端不能用在Using语句块中,因为它可能会抛出不可预知的异常。即使你捕获了异常,仍有可能一直保持连接。...

WCF客户端不能用在Using语句块中&#xff0c;因为它可能会抛出不可预知的异常。即使你捕获了异常&#xff0c;仍有可能一直保持连接。让我们来看看形成这一问题的历史原因&#xff0c;并提出几个补救措施。 在.NET中&#xff0c;资源管理的基础就是IDisposable和Using语句块。除…

关于 MongoDB 与 SQL Server 通过本身自带工具实现数据快速迁移 及 注意事项 的探究...

背景介绍 随着业务的发展、需求的变化&#xff0c;促使我们追求使用不同类型的数据库&#xff0c;充分发挥其各自特性。如果决定采用新类型的数据库&#xff0c;就需要将既有的数据迁移到新的数据库中。在这类需求中&#xff0c;将SQL Server中的数据导入到MongoDB 中显得尤为突…

语音计算矩形面积_LeetCode85-最大矩形

今天在制作书签的时候突然想到了一个问题如果要送给未来的女朋友一个书签上面该写些什么话哈哈哈哈哈哈哈哈哈The Spring is coming!想了一会儿&#xff0c;觉得这句话最合适To xxx:天使的笑&#xff0c;灿烂的心&#xff01;&#xff01;&#xff01;哎&#xff0c;还是先找个…

模板的分离编译

模板不支持分离编译我们来分析一下模板为什么不支持分离编译呢&#xff0c;所谓的分离编译就是我们在编写程序的时候可能会出现如下的一种情况就是&#xff0c;&#xff08;我下面就是举具体的例子了&#xff09;代码//*****************template.h***********// #include<i…

什么是壳 - 脱壳篇01

什么是壳 - 脱壳篇01 让编程改变世界 Change the world by program 壳 在自然界中&#xff0c;植物用壳来保护种子&#xff0c;动物用壳来保护身体&#xff0c;我们人类没有壳&#xff0c;但我们有衣服&#xff0c;房子也起到了壳的作用。不仅保护&#xff0c;而且美观。 同…

push、pop指令

push、pop指令转载于:https://www.cnblogs.com/LoveFishC/archive/2012/07/25/3846605.html

个人前端学习路线图与github优秀前端开发者的路线图推荐

1、个人目前学习的路线图 2、github优秀前端开发者的路线图推荐 打开github首页&#xff0c;在搜索框输入developer-roadmap&#xff0c;搜索github前端路线图 选择kamranahmedse/developer-roadmap拥有56.5k的星&#xff0c;足以证明这个路线受到广大前端开发者的喜爱与推荐 选…

智能指针1.0

一.使用普通的动态内存开辟存在的问题 我们在使用动态内存开辟一个空间的时候&#xff0c;需要释放掉这个空间&#xff0c;不然就容易出现内存泄漏。 比如下面的程序 情况一&#xff1a; #include<iostream> using namespace std; int errorTest() { intflag 0; …