开发工具——gcc/g++

news2024/9/21 12:39:59

开发工具gcc/g++

完成代码的编写完后,要形成可执行程序,需要编译工具进行对代码的编译。

C语言的编译工具是gcc,c++的编译工具是g++。

如果g++没有的话,可以切换到root执行命令yum  install  -y  gcc-c++

C语言和C++的编译:

gcc只能编译C语言,而g++可以编译c++也可以编译C语言。

在C语言的最后一章,已经学习了源代码到可执行程序的的简单步骤。下面来详细一点的说明。

源代码,即程序,本质上是文本;可执行程序是机器语言,也就是二进制组成的。

文本翻译成二进制要经过以下几个步骤:

预处理,编译,汇编,链接。

预处理要进行:宏替换,头文件展开,去注释,条件编译。

gcc和g++编译的过程和选项是一样的。

下面写一个包含宏,头文件,注释,条件编译的代码:

对代码进行编译,gcc test.c

如果要指定输出的可执行文件文件名需要 -o选项:gcc test.c -o mytest,-o的含义是,将程序处理后的结果写入mytest中。

这里gcc的编译是一步到位,想要得到预处理的结果,需要用到-E选项:gcc -E test.c -o test.i

-E的意思是:进行程序翻译的过程中,预处理完成就停下来。这里不带-o会把处理的结果显示到界面上,不方便查看。

vim打开test.c,进入底行模式,输入vs test.i就能比较两种有什么不同。

图示框出的部分即头文件所在路径。头文件要被拷贝进test.i中,就必须能被系统找到,要找到就必须知道头文件所在路径。

由图可知宏替换,注释,条件编译,头文件展开的效果

Ctrl + w + w可以在两个窗口之间来回切换。

下面来看一下系统的头文件:

注意:是usr路径不是user路径

所以,写代码不是包含一下头文件就完了,首先要有头文件,其次要能找到头文件。之前安装vs2019时,除了安装编译器,还要安装编译器所需要的库,也就是说老的编译器不支持新语法是因为附带安装的库中,没有新语法的库。

任何编译器都必须通过一定方式,知道包含的头文件所在路径。

在预处理完后,test.i中还是C语言,也就是说,预处理只是进行文本层面的操作。目的是为了编译更顺畅。

编译的作用:将C语言翻译成汇编语言。

关于汇编语言,不需要了解太多,只需要知道,和C语言不一样就行了。

得到编译的结果要使用-S选项:gcc -S test.i -o test.s

-S的含义:对文件进行处理的过程中,编译完成后就停下来。汇编语言的后缀是.s。

汇编的作用:将汇编语言文件翻译成二进制文件,更准确的说法是,可重定位的二进制文件。以.o或.obj结尾。

这个重定位和重定向(>、<、>>)没有关系。

查看汇编的结果需要使用-c选项:gcc -c test.s -o test.o

-c的含义:对文件进程处理的过程中,会汇编完成后就停止。

这里已经变成二进制文件了

但是仍然无法执行,即使加上x权限后依然无法执行。

原因很简单,虽然转换成二进制后可以被系统识别了,但是其中的一些函数符号,还没有和库关联起来

包含头文件是为了代码能使用头文件中包含的方法(函数)。

而在进行-E -S -c操作的对象始终是test.c,也就是说,从头到尾,只进行了test.c代码的编译。比如printf,包含的头文件,传了参数,但printf是如何实现的?printf实现的操作没有写在test.c中。printf的实现实际上是由C语言的库完成的,但刚才的过程中只编译了test.c的代码。

所以代码中需要的printf实现在哪里?代码中使用的printf如何和printf的实现产生关联?

头文件中是不包含所有函数的实现的,函数的实现存放在头文件所对应的库中。包含头文件只是方便编译。

printf的实现在C语言的标准库中,标准库一般在/lib64/libc*路径下的第一个文件中

只要调用了函数,就还需要最后一步:将使用的printf函数和库中的printf函数通过链接操作关联起来。才能实现可执行程序。

gcc不用添加任何选项,系统就会自动到特定路径下搜索所要使用的库

gcc test.o -o mytest的隐含操作就是链接自己和程序和库,形成可执行程序。

使用ldd指令可以查看可执行程序所依赖的库。

libc.so.6是一个链接文件,指向C语言标准库

Linux平时使用的命令也可能是由C语言写的,可以查看一下。

还有其他的很多文件都会用到C语言标准库。如果删除C语言标准库,那么很多文件和命令都会无法实现。

如果需要记忆预处理,编译,汇编指令的选项,有一个简单的记忆技巧:-E-S-c和esc键只有大小写的区别。形成的对应文件后缀合在一起则是iso,国际标准化组织的简称,也是镜像文件的后缀。

在最开始的学习中,包含头文件被认为是函数声明;在编写代码的时候,比如输入一个函数,会有语法提示,本质上就是通过对头文件进行搜索来完成语法提示的。

而库文件中则存在函数的实现,以供链接,形成自己的可执行程序。

动态库和静态库

动态库和静态库的内容也很多,先基本的认识一下

Linux下动态库后缀:.so;Windows下动态库后缀:.dll

Linux下静态库后缀:.a;Windows下静态库后缀:.lib

下面用一个故事简单介绍一下动态链接,静态链接:

假设你是一个科研人员,你所在的科研机构有一台超级计算机,在进入科研机构的时候,你就被告知超级计算机的位置。一天的日程安排如下:起床,吃饭,做实验,收集数据,用超级计算机分析数据,写报告,和同事聊天……在分析数据之前的行为自己可以独立完成,要分析数据,必须借助于超级计算机,好在知道超级计算机的位置,找到超级计算机,找出对应实验的分析方法,完成数据分析后,分析数据的任务完成,再返回到日程安排中,进行下一项任务。

一天的日程安排就相当于自己写的代码,分析数据就相当于某个需要动态库的函数。在还没有分析数据前就已经知道动态库的位置,这叫做将函数和动态库关联起来,也就是链接的过程(链接不是执行,链接是产生关系)。当开始执行代码时,执行到需要动态库的函数时,就跳转库中(超级计算机),找到对应的函数实现(找出对应实验的分析方法) ,执行完毕后再返回,继续向后运行。

自己的日程行为就相当于自己写的代码,超级计算机中的实验分析方法就相当于库提供的函数实现,这种链接方式就叫做动态链接。动态链接的本质就是,在链接的时候,把需要的函数和库中的位置通过地址的方式关联起来。

科研机构中,需要使用超级计算机的不止一人,超级计算机是被所有科研人员所共享的。类比到系统当中,动态库就相当于超级计算机,被系统中所有文件和命令所共享。

静态链接本质上就是将库中的相关代码直接拷贝到相关程序中。比如有十个printf,每个printf都要把实现自己拷贝一份。静态链接后的程序,只要编译通过,就可以不要库,库只会使用一次。

动态链接的优缺点

优点:大家共享一个库,可以节省资源

缺点:一旦库缺失,会导致几乎所有程序失效。

静态链接的优缺点

优点:不依赖任何库,程序可以独立执行。

缺点:浪费资源。

可以通过file指令查看可执行程序的构成:

从框出来的内容来看,mytest是一个可执行程序,通过动态链接完成。

默认情况下,生成的可执行程序是通过动态链接完成的。

如果想要通过静态链接生成可执行程序,那么需要使用-static选项:gcc test.c -o mytest2 -static

-static选项需要安装静态库

安装指令:yum install -y glibc-static,这是C语言的静态库

安装指令:yum install -y libstdc++-static,这是C++的静态库

在仅仅使用printf函数的情况下,动态链接和静态链接的可执行文件大小差了近100倍。

再对mytest2使用ldd指令,就会弹出mytest2不是动态可执行的,file mytest2可以看到,静态链接。

正常情况下,动态链接的使用情况更多。默认情况下使用的是动态链接,甚至默认状态下是不带静态库的。但是如果软件要安装到别人的系统下,而别人的系统没有安装对应的库,这时候静态库就是必要的了。进行动态链接使用动态库,进行静态链接使用静态库。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「点燃我,温暖你」用Python制作一个动态爱心效果

最近「点燃我&#xff0c;温暖你」这部剧非常火&#xff0c;讲述的是程序员的爱情故事。 其中陈飞宇饰演的男主李峋&#xff0c;在剧中用程序做出的爱心跳动效果&#xff0c;非常炫。 网上各个大佬也是纷纷给出看法&#xff0c;综合就是不太可能用C语言来实现的。 大概率是AE…

Reg注册表读写

在Windows 95及其后继版本中&#xff0c;采用了一种叫做“注册表”的数据库来统一进行管理&#xff0c;将各种信息资源集中起来并存储各种配置信息。按照这一原则&#xff0c;Windows各版本中都采用了将应用程序和计算机系统全部配置信息容纳在一起的注册表&#xff0c;用来管理…

Java内存溢出故障案例及Linux内存机制探究

文章目录Java内存溢出故障案例及Linux内存机制探究OOM Killer触发机制分析如何避免系统触发OOM Killer这部分内容属于demo案例分享&#xff0c;解决线上运维问题&#xff0c;思路是最重要的 Java内存溢出故障案例及Linux内存机制探究 这是一个线上数据分析应用故障案例&#…

Java—反射

文章目录什么是反射反射定义java创建对象的三个阶段反射过程反射第一步&#xff1a;获取类对象获取类对象的三种方式反射第二步&#xff1a;获取类信息如何获取类信息&#xff1f;1、获取成员变量&#xff1a;2、获取方法&#xff1a;3、获取构造器反射第三步&#xff1a;使用反…

vue学习笔记——简单入门总结(四)

文章目录1.Vue3的特性和变化1.1.创建vue3项目1.2.分析main.js变化&#xff1a;1.3.setup--组合式api的开端1.4.ref函数和reactive函数&#xff1a;1.5.watch监视属性1.5.watchEffect函数1.6.vue3生命周期&#xff1a;1.Vue3的特性和变化 1.1.创建vue3项目 1.这里我们使用脚手架…

RegAD-Registration based Few-Shot Anomaly Detection论文学习

摘要 本文为少样本异常检测&#xff08;FSAD&#xff09;&#xff0c;这是一种实用但尚未被研究的异常检测&#xff08;AD&#xff09;&#xff0c;少样本意味着在训练中只为每个类别提供有限数量的正常图像。 现有的少样本异常检测的研究主要使用的是 一类别一模型 学习范式…

李宏毅《DLHLP》学习笔记7 - Voice Conversion

视频链接&#xff1a;https://www.youtube.com/watch?vJj6blc8UijY&listPLJV_el3uVTsO07RpBYFsXg-bN5Lu0nhdG&index9&ab_channelHung-yiLee 课件链接&#xff1a;https://speech.ee.ntu.edu.tw/~tlkagk/courses/DLHLP20/Voice%20Conversion%20(v3).pdf 1. 语音转…

JAVA+MySQL 图书馆借阅信息管理系统

图书馆是当下很多大学生和有志青年学习和借阅图书的场所,图书馆每天都有大量的人员需要接待,如何能够更好的对用户的这些借阅信息进行信息化的管理是当下大多数图书馆管理人员所关心的问题 本系统是通过JAVA和MYSQL来进行开发的,通过本系统可以对图书馆内的图书信息,用户信息以…

基于PCIe的NVMe协议在FPGA中实现方法

NVMe协议是工作在PCIE的最上层协议层的&#xff0c;故需要先搞清楚PCIE。本文基于Xilinx的UltraScale&#xff0c;开发工具为Vivado2021.2。学习中以spec为主&#xff0c;其它资料辅助参考(重点介绍学习方法及资料&#xff0c;有时间再加细节)。请勿转载&#xff01; 1 PCIe学…

基于PHP+MySQL青年志愿者服务管理系统的设计与实现

志愿者管理系统能够通过互联网得到广泛的、全面的宣传,让尽可能多的人积极的参加到志愿者行列中来,不仅为需要的人提供了服务,而且锻炼了自己,志愿者是一个对社会和自己以及需要帮助的人都有很多好处的事情 PHP青年志愿者服务网站是一个公益类型的网站,系统通过PHp&#xff1a;…

HK1 BOX刷入 Armbian系统作为服务器

HK1 BOX刷入 Armbian系统作为服务器 1 安装Armbian到EMMC 硬件 HK1 BOX s905 x3 固件版本选择 Armbian_23.02.0_Aml_s905x3_bullseye_5.15.80_server_2022.12.01用usb启动&#xff0c;tf/sd有的设备不行&#xff0c;有干扰&#xff0c;有可能从TF卡无法启动系统。 用usb启…

Grid 布局实现九宫格图片动画

前言 &#x1f44f;Grid 布局实现九宫格&#xff0c;background-position设置背景图像起始位置&#xff0c;速速来Get吧~ &#x1f947;文末分享源代码。记得点赞关注收藏&#xff01; 1.实现效果 2.实现步骤 定义css变量&#xff1a;九宫格中每个宫格的长/宽为w&#xff0c…

Kafka - 14 Kafka消费者 | 分区的分配策略及再平衡 | Range | RoundRobin | Sticky | CooperativeSticky

文章目录1. 分区的分配以及再平衡2. Range 分区分配以及再平衡3. RoundRobin 分区分配以及再平衡4. Sticky 分区分配以及再平衡1. 分区的分配以及再平衡 一个consumer group中有多个consumer组成&#xff0c;一个 topic有多个partition组成&#xff0c;现在的问题是&#xff0…

【Python自然语言处理】规则分词中正向、反向、双向最大匹配法的讲解及实战(超详细 附源码)

需要源码和字典集请点赞关注收藏后评论区留言私信~~~ 一、规则分词 规则分词核心内容是建立人工专家词典库&#xff0c;通过将语句切分出的单词串与专家词典库中的所有词语进行逐一匹配&#xff0c;匹配成功则进行对象词语切分&#xff0c;否则通过增加或者减少一个字继续比较…

文件或者文件夹的忽略

文件或者文件夹的忽略 编辑项目的时候&#xff0c;将一些临时文件或者插件可以忽略上传到项目库中去。 追踪中的文件&#xff0c;不能被忽略。 首先的创建.gitignore文件&#xff0c;并且该文件需要放到项目的根目录下 接着&#xff0c;打开.gitignore文件 windows中 open d…

软件测试——分类

测试分类 一、按照测试对象划分 1、界面 界面测试UI测试 &#xff08;1&#xff09;测试软件界面元素完整性&#xff0c;正确性&#xff0c;一致性 &#xff08;2&#xff09;软件界面排版布局合理、字体、颜色 &#xff08;3&#xff09;测试界面的自适应性&#xff0c;界面…

1549_AURIX_TC275_SCU系统中的CCU模块

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 从这一份笔记开始看一下SCU系统&#xff0c;其实这个是一个功能组合&#xff0c;其中的一个小模块又叫做SCU。因此&#xff0c;在名称上可能会有一点点绕。近段时间看相关的资料比较多&…

数据结构与算法—数组栈和链表栈

数据结构与算法—数组栈和链表栈 &#x1f308;一览众山小数据结构与算法—数组栈和链表栈栈介绍栈图解栈实现数组实现栈实现思路实现代码单链表实现栈实现思路(图解)实现代码栈总结栈力扣栈介绍 栈,存储货物或供旅客住宿的地方,可引申为仓库、中转站&#xff0c;所以引入到计算…

Java—泛型、内部类、多继承

文章目录泛型1.泛型是什么&#xff0c;使用泛型的好处2.泛型中的限定通配符和非限定通配符3.泛型擦除内部类多继承多继承使用&#xff1a;———————————————————————————泛型 1.泛型是什么&#xff0c;使用泛型的好处 ​ 泛型就是把类型参数化&…

骰子游戏-第11届蓝桥杯Scratch选拔赛真题精选

[导读]&#xff1a;超平老师计划推出Scratch蓝桥杯真题解析100讲&#xff0c;这是超平老师解读Scratch蓝桥真题系列的第94讲。 蓝桥杯选拔赛每一届都要举行4~5次&#xff0c;和省赛、国赛相比&#xff0c;题目要简单不少&#xff0c;再加上篇幅有限&#xff0c;因此我精挑细选…