当前位置: 首页 > news >正文

Linux编译器-gcc或g++的使用

一.安装gcc/g++

在linux中是不会自带gcc/g++的,我们需要编译程序就自己需要安装gcc/g++。

很简单我们使用简单的命令安装gcc:sudo yum install -y gcc

g++安装:sudo yum install -y gcc-c++

我们知道Windows上区分文件,都是使用文件后缀来区分的,.txt是文本文件,.mp4是视频文件,.md是markdown文件等等。

在linux中一切皆文件,一个文件可以随便取名字,但是这样好吗?不见得。比如下面这样。

image-20240606150226762

test.txt文件中我编写的是c代码,使用gcc编译器编译该文件,显然从结果来看,是编译不过的。

使用mv修改test.txt为test.c,再使用gcc编译就能编译过了。

image-20240606150515492

结论:虽然linux中不关心文件的后缀,但是gcc/g++是要区分文件后缀的,gcc编译.c后缀的c文件,g++编译.cc/.cpp后缀的c++文件。

二.一个文件到可执行程序的步骤

在我们编一个源文件的时候,使用gcc或者g++时,都会直接生成可执行程序。
那为什么要生成可执行程序呢?因为机器只认识二进制语言,它可不懂什么代码,汇编,我们的目的就是把源代码变成机器语言,也就是二进制语言。

其实生成可执行程序之前都会有好几个步骤的:

先经过预处理,再编译,在汇编,在进行链接生成可执行程序,接下来我们就一步一步探讨一下具体步骤的作用。

1.预处理

预处理的主要功能:

①头文件的展开
②去注释
③条件编译
④宏替换

预处理的命令:gcc -E test.c -o test.i

这里的-E就是预处理的意思,-o是生成test.i文件。

编写代码来验证一下。

 #include<stdio.h>2 #define M 103 4 #define v1 15 int main()6 {7     //这是条件编译                                                          8 #if v19     printf("这是普通版本的\n");10 #elif v211     printf("这是会员版本的\n");12 #else13     printf("这是超级会员版本的\n");14 #endif15   printf("%d",M);18     return 0;19 }

image-20240606155315253

可以看出上面几百行全是stdio头文件的展开,然后我们写的注销也全部没有了,定义的宏M也被替换成了10,条件编译也成功的实现了,通过条件编译,可以实现对代码的动态裁剪

2.编译

编译就是把预处理后的文件生成汇编的过程。

编译的命令:gcc -S test.i -o test.s

验证:

image-20240606155436535

可以看出这里就是各种汇编的指令,我们也看不懂。

3.汇编

汇编也就是把汇编语言变成二进制语言。

汇编的命令:gcc -c test.s -o test.o

image-20240606160417442

这就是可被机器识别的目标文件(obj文件)。

4.链接

链接就是生成可执行程序。

链接命令:gcc test.o

链接可不是这么简单就完了,它还牵扯到库文件,待会细说。

三.gcc选项记忆

上面我们说到预处理,编译等,使用的命令是不是不好记,这里有个好记忆的方法。

使用的命令-E -S -c刚好对于键盘上的键ESC,只不过要记清楚,ES是大写,c是小写的。

依次生成的文件是iso,而在Windows中,iso是光盘镜像文件。

这样联系起来也就比较好记了。

但是我们实际上我们得到可执行文件,可不用这么复杂,直接使用gcc该文件即可。

四.函数库之静态库和动态库

对于printf函数这些,为什么我们代码中写了,电脑就知道它实现的是什么功能呢?

因为我们包含了头文件?也不全对,因为stdio头文件只是各种声明,还有各种宏定义而已。

我们现在所写的代码都是站在巨人的肩膀上,已经有人帮我们写好了可以直接可以使用的函数,也就是函数的实现,那这些函数在哪里呢?我怎么没有看到。

这就要引出来我们要说的库了,库包含各种函数的实现。

可执行程序=我们写的代码+头文件+库。

使用命令ls /lib64/libc.so.6可以查看库的位置。

image-20240606171237816

而库也分为静态库和动态库。默认情况下,云服务器上是没有安装c静态库的,只有动态库。

一般来说,linux中.so为动态库,Windows中.dll为动态库。

linux中.a为静态库,Windows中.lib为静态库。

安装c++静态库的命令:sudo yum install -y libstdc+±static。
安装c静态库的命令:sudo yum install -y glibc-static。

动态库是c/c++或者其他第三方提供的所有方法的集合,被所有程序以链接的方式关联起来。(动态链接)

这里的动态链接是库中所有的函数,都有入口地址,所谓的动态链接,其实就是把要连接的库中的函数地址拷贝到我们的可执行程序的特定位置!

静态库是c/c++或者其他第三方提供的所有方法的集合,被所有程序以拷贝的方式,将需要的代码,拷贝到自己的可执行程序中。(静态链接)

我们可以将test.文件分别使用静态链接和动态链接得到可执行程序,来看看有什么区别。

动态链接:

image-20240606184328750

静态链接:

image-20240606185725454

test-d是动态链接出来的可执行文件,而test-s是静态链接出来的可执行文件,可以很清晰的看出,静态链接出来的可执行程序的文件大小是远大于动态链接的。

这里就可以总结出它们的优缺点了。

动态链接的优点:形成的可执行程序体积较小,比较节省资源的!
缺点:强依赖动态库,动态库没了,所有的依赖这个库程序都无法运行了。

静态库的优点:无视库,可以独立运行。
缺点:体积太大,浪费资源。

就像刚开始我们下载vs开发环境的时候,下载安装包内存不大,当我们选择c/c++下载得到时候,大小就会达到几个G。
这是因为当我们下载的开发环境的时候,它默认会为我们做以下工作:

①下载头文件,lib。
②设置合理的查找路径。

相关文章:

  • 区间预测 | Matlab实现QRCNN-BiGRU-Attention分位数回归卷积双向门控循环单元注意力机制时序区间预测
  • 数据流图(DFD)绘制规范
  • Visual 怎么编程:一场视觉与逻辑的奇妙旅程
  • 7.0 android中Service的基础知识
  • BeagleBone Black入门总结
  • 四种跨域解决方案
  • 初识C++ · 模拟实现list
  • 从零手写实现 nginx-11-文件处理逻辑与 range 范围查询合并
  • 使用Python操作Redis
  • Redis 内存回收
  • Debezium日常分享系列之:Debezium 2.6.2.Final发布
  • Nginx(openresty) 查看连接数和并发送
  • 【SpringCloud学习笔记】Docker(上篇)
  • 提高篇(五):使用Processing创作互动艺术:从灵感到实现
  • QUIC 的多路径扩展
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 2019.2.20 c++ 知识梳理
  • Angular数据绑定机制
  • JavaScript创建对象的四种方式
  • JavaScript类型识别
  • java正则表式的使用
  • Python爬虫--- 1.3 BS4库的解析器
  • Python实现BT种子转化为磁力链接【实战】
  • 坑!为什么View.startAnimation不起作用?
  • 前端技术周刊 2019-01-14:客户端存储
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 试着探索高并发下的系统架构面貌
  • 我的面试准备过程--容器(更新中)
  • 学习笔记:对象,原型和继承(1)
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • ​卜东波研究员:高观点下的少儿计算思维
  • # Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型
  • ### RabbitMQ五种工作模式:
  • #if 1...#endif
  • #Linux(Source Insight安装及工程建立)
  • (09)Hive——CTE 公共表达式
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (七)Flink Watermark
  • (亲测有效)推荐2024最新的免费漫画软件app,无广告,聚合全网资源!
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (四)stm32之通信协议
  • (转)平衡树
  • (轉貼) UML中文FAQ (OO) (UML)
  • (自用)仿写程序
  • .htaccess配置重写url引擎
  • .Net 8.0 新的变化
  • .NET Core 2.1路线图
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET Reactor简单使用教程
  • .Net Remoting(分离服务程序实现) - Part.3
  • .NET 材料检测系统崩溃分析
  • .NET 服务 ServiceController
  • .NET 解决重复提交问题