linux下的程序环境和预处理(gcc演示)

1. 程序的翻译环境和执行环境

     在ANSI C的任何一种实现中,存在两个不同的环境。

        第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。
        第2种是执行环境,它用于实际执行代码。

2. 详解编译+链接

        2.1 翻译环境

        组成一个程序的每个源文件通过编译过程分别转换成目标代码(object code)。
        每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。
        链接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且它可以搜索程序员个人的程序库,将其需要的函数也链接到程序中。

        2.2 编译本身也分为几个阶段:

        1. 预处理(1.头文件展开2.去注释3.进行宏替换4.条件编译)
        2. 编译(生成汇编)
        3. 汇编(生成机器可识别代码)
        4. 连接(生成可执行文件或库文件)

        gcc如何完成
        格式 gcc [选项] 要编译的文件 [选项] [目标文件]

 预处理(进行宏替换)
        预处理功能主要包括宏定义,文件包含,条件编译,去注释等。
        预处理指令是以#号开头的代码行。
        实例: gcc –E hello.c –o hello.i
        选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
        选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。

这是我们使用vim写的一段小代码 

        我们通过程序控制,使其在预处理完之后就停下

        预处理之后的代码总共有八百多行,而上面我们写的代码才短短几行,那么多余的代码是从哪里来的呢?  

        1.头文件展开

这一段代码是我们mybin中的一段代码,是关于printf的

通过一下指令找到库中的stdio.h

通过对比这两个代码我们发现两个竟然相同,说明头文件在预处理之后进行了展开 

        通过我们生成的mybin文件还可以看出来注释没有了,宏也进行了替换。

        

我们再写一段小代码,通过定义不同的宏来说明确实存在条件编译

        通过不同的宏,函数执行的结果确实不同。 说明确实存在条件编译这回事。

 这时我们在修改程序,将两个定义的宏给注释掉

        这时通过这一行指令,将程序在预处理完后停下来,-DVERSION1 是相当于对程序添加一个宏(#define VERSION1 1)

        那么这个宏到底添加了吗?我们看自己生成的mybin

        确实添加上了,并且也可以说明条件编译也是在预处理阶段完成的。

编译(生成汇编)
        在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。
        用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
        实例: gcc –S hello.i –o hello.s

汇编(生成机器可识别代码)
        汇编阶段是把编译阶段生成的“.s”文件转成目标文件
        读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了
        实例: gcc –c hello.s –o hello.o

一堆二进制语言。

连接(生成可执行文件或库文件)
        在成功编译之后,就进入了链接阶段。
        实例: gcc hello.o –o hello

在这里涉及到一个重要的概念:函数库

        静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”
        动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。 gcchello.o –o hello
        gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证。

gcc选项

        -E(大写) 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
        -S(大写)  编译到汇编语言不进行汇编和链接
        -c (小写) 编译到目标代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/112213.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL连接的原理⭐️4种优化连接的手段性能提升240%

MySQL连接的原理⭐️4种优化连接的手段性能提升240%🚀 前言 上两篇文章我们说到MySQL优化回表的三种方式:索引条件下推ICP、多范围读取MRR与覆盖索引 MySQL的优化利器⭐️索引条件下推,千万数据下性能提升273%🚀 MySQL的优化…

函数式接口详解(Java)

函数式接口详解(Java)_函数式接口作为参数_凯凯凯凯.的博客-CSDN博客 函数式接口:有且仅有一个抽象方法的接口 Java中函数式编程体现就是Lambda表达式,所以函数式接口就是可以适用于Lambda使用的接口 只有确保接口中仅有一个抽…

【设计模式】第7节:创建型模式之“建造者模式”

Builder模式,中文翻译为建造者模式或者构建者模式,也有人叫它生成器模式。 在创建对象时,一般可以通过构造函数、set()方法等设置初始化参数,但当参数比较多,或者参数之间有依赖关系,需要进行复杂校验时&a…

Springboot 集成 Seata

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。Seata官网 1.找到适合的Seata版本 参考:SpringCloudAlibaba S…

Linux学习之进程二

目录 进程状态 R (running)运行状态与s休眠状态: disk sleep(深度睡眠状态) T (stopped)(暂停状态) t----tracing stop(追踪状态) X死亡状态(dead) Z(zombie)-僵尸进程 孤儿进程 进程优…

python捕获异常和scapy模块的利用

Python捕获异常 ​ 当程序运行时,因为遇到未知的错误而导致中止运行,便会出现Traceback 消息,打印异常。异常即是一个事件,该事件会在程序执行过程中发生,影响程序的正常执行。一般情况下,在Python 无法正…

2023年Q3户外装备市场行业分析报告(京东数据分析):同比增长7%,品牌化发展是核心

近年来,户外运动在我国不少地方蓬勃兴起,发展至今,户外运动早已不是聚焦专业领域的小众群体活动,现已发展成为当下热门的大众休闲活动,参与人群愈发广泛,而这股热潮也带动着相关产业的发展。 今年Q3&#x…

IT老鸟给开发者升职加薪的小技巧

前言: 升职加薪对大多数人来说都是工作重要动力所在,但总存在“青出于蓝而胜于蓝”,后来人居上的情况。很多人不清楚,自己兢兢业业,任劳任怨,到头来还是得不到领导的重视,身边一起过来的同事都成…

GZ035 5G组网与运维赛题第7套

2023年全国职业院校技能大赛 GZ035 5G组网与运维赛项(高职组) 赛题第7套 一、竞赛须知 1.竞赛内容分布 竞赛模块1--5G公共网络规划部署与开通(35分) 子任务1:5G公共网络部署与调试(15分) 子…

单元测试到底测什么,怎么测?我来告诉你

前言: 以国内互联网的开发节奏,在前端业务项目中全面覆盖单元测试有时显得不太可行,主要是因为以下这些绊脚石: UI 交互复杂,路径难以覆盖全面 工期紧,开发对实践 TDD,BDD 所带来的长远效益没有…

Arduino开发

文章目录 资源Arduino IDE 的使用1. 使能编译以及烧录的LOG:2. 下载配置3. 下载 Arduino指令程序下载步骤通过下载器下载通过串口下载 关于Arduino IDE工程生成的二进制文件对比Tools-->burn bootloader 和 ArduinoISP例程 的区别自带例程 资源 Arduino通过串口…

解决MySQL大版本升级导致.Net(C#)程序连接报错问题

数据库版本从MySQL 5.7.21 升级到 MySQL8.0.21 数据升级完成后&#xff0c;直接修改程序的数据库连接配置信息 <connectionStrings> <add name"myConnectionString" connectionString"server192.168.31.200;uidapp;pwdFgTDkn0q!75;databasemail;&q…

【缓存】Spring全家桶中@CacheEvict无效情况共有以下几种

Spring全家桶中CacheEvict无效情况共有以下几种 一、背景介绍二、原因分析三、解决方案 一、背景介绍 SpringBoot中使用Cacheable注解缓存数据&#xff0c;使用CacheEvict注解删除缓存。但是在项目使用过程中&#xff0c;发现使用CacheEvict注解删除缓存无效。 拓展&#xff…

猪八戒、程序员客栈、码市哪个更好用?

最近有很多程序员伙伴在用接单平台线上兼职&#xff0c;问题也来了&#xff1a;到底哪个更好用嘞? 选取了几个问的比较多的&#xff1a;猪八戒、程序员客栈、码市。进行了一下简单的比较。 优点: 猪八戒 第一&#xff0c;猪八戒的名气是毋庸置疑的。无论是它成立至今的时间…

NB-IOT的粮库挡粮门异动监测装置

一种基于NBIOT的粮库挡粮门异动监测装置,包括若干个NBIOT开门监测装置,物联网后台管理系统,NBIOT低功耗广域网络和用户访问终端;各个NBIOT开门监测装置通过NBIOT低功耗广域网络与物联网后台管理系统连接,物联网后台管理系统与用户访问终端连接.NBIOT开门监测装置能够对粮库挡粮…

索引创建的原则

索引的创建是数据库优化中非常重要的一部分&#xff0c;正确创建索引可以大大提高查询效率。以下是一些创建索引时需要考虑的原则&#xff1a; 根据查询频率创建索引&#xff1a; 频繁用于检索的列&#xff1a; 那些频繁用于查询的列或经常出现在 WHERE、JOIN、ORDER BY 和 GR…

企业如何在自媒体平台推广

自媒体是企业宣传品牌的平台之一&#xff0c;在自媒体平台上企业能够较为自由的决定文案内容发布时间&#xff0c;同时后台也会有专门的数据分析帮助企业了解每一次推广效果&#xff0c;成本可控、数据可查、效果可追踪&#xff0c;还能与用户或者潜在用户互动&#xff0c;进行…

放射影像科PACS系统源码

PACS系统是医院影像科室中应用的一种系统&#xff0c;主要用于获取、传输、存档和处理医学影像。它通过各种接口&#xff0c;如模拟、DICOM和网络&#xff0c;以数字化的方式将各种医学影像&#xff0c;如核磁共振、CT扫描、超声波等保存起来&#xff0c;并在需要时能够快速调取…

从用户角度出发,如何优化大数据可视化体验|北京蓝蓝UI设计公司

作者&#xff1a;蓝蓝设计-鹤鹤 大数据已经成为人们探索世界的新工具。但是&#xff0c;对于普通用户而言&#xff0c;大数据往往比较抽象和难以理解&#xff0c;因此&#xff0c;大数据可视化作为一种非常有效的工具工具被广泛应用。然而&#xff0c;在实际应用中&#xff0c…

前端如何不变形的渲染图片大小和图片上的内容

在做前端项目时可能经常会页面图片大小变形或者压缩的情况&#xff0c;一般情况就是height给100%&#xff0c;width给auto就可以了满足大部分使用情况了。有时候需要做一些比较复杂的功能&#xff0c;比如需要在图片上增加锚点&#xff0c;而且图片在适配各种屏幕大小时&#x…
最新文章