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

[Linux入门]---Linux编译器gcc/g++使用

文章目录

  • 1.背景知识
  • 2.gcc如何完成编译运行工作
    • 预处理(进行宏替换)
    • 编译(生成汇编)
    • 汇编(生成机器可识别代码)
    • 链接(生成可执行文件)
  • 3.函数库
    • 动态库
    • 静态库
    • 动静态库的区别
  • 4.gcc选项

1.背景知识

通过前面的学习,我们知道我们的代码变成能运行的可执行程序,要经历以下四个过程:

1.预处理(进行宏替换)
2.编译(生成汇编)
3.汇编(生成机器可识别的代码)
4.链接(生成可执行文件或库文件)

那在Linux操作系统上gcc编译器编译运行代码的过程又是怎么样的呢?接下来让我们一起学习吧!

2.gcc如何完成编译运行工作

$ 格式 gcc [选项] 要编译的文件 [选项] [目标文件]

创建mycode.c文件,写入如下代码:

#include<stdio.h>      
#define M 100      int main()      
{      
#ifdef DEBUG      printf("hello debug\n");      
#else      printf("hello release\n");      
#endif      // pintf("这是被注释掉的内容\n");    // pintf("这是被注释掉的内容\n");    // pintf("这是被注释掉的内容\n");    // pintf("这是被注释掉的内容\n");    // pintf("这是被注释掉的内容\n");    // pintf("这是被注释掉的内容\n");    printf("hello gcc:%d\n",M);                                                                                                            printf("hello gcc:%d\n",M);                                                                                                            printf("hello gcc:%d\n",M);                                                                                                            printf("hello gcc:%d\n",M);                                                                                                            printf("hello gcc:%d\n",M);                                                                                                            printf("hello gcc:%d\n",M);                                                                                                            printf("hello gcc:%d\n",M);                                                                                                            printf("hello gcc:%d\n",M);                         printf("hello gcc:%d\n",M);    printf("hello gcc:%d\n",M);    printf("hello gcc:%d\n",M);    return 0;    
} 

指令:

$ gcc -o mycode.exe mycode.c
//-o 可以指定生成可执行文件名称,如果不指定,默认生成a.out可执行文件

代码编译运行的结果为:
在这里插入图片描述

预处理(进行宏替换)

预处理指令:

$ gcc -E 源文件 -o 指定预处理文件名
  • 预处理阶段是源文件文件转成目标文件
  • 选项-E,该选项的作用是让 gcc 在预处理结束后停止编译过程。
  • 选项“-o”是指目标文件,如果不带选项“-o”会预处理的结果放在显示屏上,“.i”文件为已经过预处理的C原始程序。
  • 预处理阶段的主要工作有:a.去注释,b.头文件展开;c.宏替换(不做类型检查);d.条件编译;

输入指令:

$ gcc -E mycode.c -o mycode.i
$ gcc -E mycode.c -o mycode.i -D DEBUG//使用-D选项在外部可定义宏

在这里插入图片描述

输入该指令告诉gcc从现在开始程序的翻译,做完预处理工作就停下来,不要继续往下执行了。

输入指令vim mycode.i查看预处理后的文件
头文件展开:
在这里插入图片描述
在这里插入图片描述

编译(生成汇编)

输入编译指令:

$ gcc -S mycode.i -o mycode.s
  • 编译阶段是把预处理阶段生成的“.i”文件转成".s"目标文件
  • 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。
  • 用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。

代码运行的结果为:
在这里插入图片描述
在这里插入图片描述

汇编(生成机器可识别代码)

汇编指令:

$ gcc -c mycode.s -o mycode.o
  • 汇编阶段是把编译阶段生成的“.s”文件转成".o"目标文件
  • 可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了
    输入指令的结果为:
    在这里插入图片描述
    在这里插入图片描述

mycode.o为可重定位二进制文件,简称目标文件,Windows上目标文件为.obj文件,虽然已经是二进制文件,但是还不可以独立执行,需要经过链接才能执行!

链接(生成可执行文件)

$ gcc mycode.o -o mycode.exe
  • 在成功编译之后,就进入了链接阶段,将可重定位二进制文件和库进行链接形成.exe可执行文件
    在这里插入图片描述

3.函数库

函数库概念:
我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?

系统把这些函数实现都被做到名为 libc.so.6的库文件中去了,在没有特别指定时,gcc会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到libc.so.6库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用!

动态库

windows系统中,动态库以.dll为后缀的文件,Linux系统,动态库为以.so为后缀的文件。库的命名规则:“libnameso.XXX"name为库的真正名字,其他为前后缀。
输入指令查找C的标准库:

ls /lib64/libc*
//查找含/lib64/libc的库文件
ls /lib64/libc.so*
//查找动态库文件

输入指令后代码运行的结果:
在这里插入图片描述

静态库

windows系统中,静态库以.lib为后缀的文件,Linux系统,静态库为以.a为后缀的文件。我们的机器上默认只会安装动态库,静态库需要我们手动输入指令安装。
安装C语言静态库指令如下:

//root用户
# yum install -y glibc-static//安装c的静态库
# yun install -y libstdc++-static//安装c++的静态库
//普通用户
$ sudo yum install -y glibc -static
$ yun install -y libstdc++-static

安装完成的结果如下:
在这里插入图片描述
在这里插入图片描述

查找C语言静态库指令:

$ ls /lib64/libc.a*

输入指令后代码运行的结果:
在这里插入图片描述

动静态库的区别

小故事: 网瘾少年需要上网,你有两种方法,一种是跑到网吧上网,而你怎么知道哪里有网吧呢?原来你的好基友曾经告诉你某某路口向东转500米有一家网吧,于是每到放假的时候,你就可以跑到网吧去上网,但天有不测风云,这家网吧的老板没有营业执照被查封了,自此你的上网之路就断了;只好使用另一种方法,你每天上省吃俭用,终于三个月后攒够了钱,去一家二手电脑销售店购买了一台电脑,从此你便过上了自由自在的网民生活,不久后你去的这家二手电脑销售店由于非法经营被查封了,但这已经影响不到你了。

动态链接:.o文件(网瘾少年)和动态库(网吧)链接,很高效但如果动态库没了,各个程序文件将无法运行,限制性很大;静态链接:.o文件(网瘾少年)会拷贝(购买)静态库(电脑)到文件中,会占用很大内存、很多时间(费时费钱),但库文件(电脑销售店没了)不存在了,各个程序文件不受影响仍可以正常运行!
生成可执行文件的指令:

$ gcc mycode.c -o mycode.exe//进行动态链接
$ gcc mycode.c -o mycode_static.exe -static//进行静态链接

输入指令后代码运行的结果:
在这里插入图片描述

ldd 可执行文件//查找链接的动态库

在这里插入图片描述

file 可执行文件名//显示符号链接的文件类型

在这里插入图片描述

①在Linux中,编译形成可执行程序,由编译器提供动态库,默认采用动态链接;如果想要以静态链接的方式,生成可执行文件,需要添加-static选项;②静态链接生成的可执行文件比动态链接生成的可执行文件大很多。

动静态库区别总结:
①如果没有静态库,不可以使用-static选项进行静态链接;
②如果没有动态库,只有静态库,gcc编译器将会去寻找静态库进行链接;
③gcc默认优先动态链接,-static选项改变的是链接的优先级,使用后所有的链接都为静态链接;
④我们平时写的代码生成可执行文件时,不一定全部是动态链接或静态链接,而极有可能是动态链接和静态链接混合生成可执行文件;
⑤动态链接优点:动态库是共享库,可以有效地节省资源(磁盘空间、内存空间,网络空间等);缺点:动态库一旦缺失,使用动态链接的可执行程序将无法运行!
⑥静态链接的优点:不依赖库,程序可以独立运行;缺点:生成的可执行文件体积大,比较消耗资源(磁盘空间、内存空间,网络空间等)。

4.gcc选项

-E 进行预处理工作,不生成文件,你需要把它重定向输出到一个.i文件里面
-S 编译到汇编语言到.s文件中,不进行汇编和链接
-c 进行汇编工作,编译到.o可重定位二进制目标文件(目标文件)
-o 将目标文件和库文件进行链接输出到指定的可执行文件
-static 此选项对生成的文件采用静态链接 -g 生成调试信息。GNU 调试器可利用该信息。
-shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库
-O0
-O1
-O2
-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-w 不生成任何警告信息。
-Wall 生成所有警告信息。

相关文章:

[Linux入门]---Linux编译器gcc/g++使用

文章目录 1.背景知识2.gcc如何完成编译运行工作预处理&#xff08;进行宏替换&#xff09;编译&#xff08;生成汇编&#xff09;汇编&#xff08;生成机器可识别代码&#xff09;链接&#xff08;生成可执行文件&#xff09; 3.函数库动态库静态库动静态库的区别 4.gcc选项 1.…...

[Git入门]---gitee注册及代码提交

文章目录 1.Gitee是什么2.gitee注册3.git工具及图形化界面工具安装4.gitee仓库创建5.进行本地仓库与远端gitee仓库的链接6.git三板斧addcommitpush 7.gitee提交代码常见问题 1.Gitee是什么 gitee是基于git代码托管和研发协作的国内平台&#xff0c;在上面可以托管个人或公司代…...

企业架构LNMP学习笔记46

PHP测试连接代码&#xff1a; php代码测试使用memcached&#xff1a; 示例代码&#xff1a; <?php //实例化类 $mem new memcached(); //调用连接memcached方法 注意连接地址和端口号 $mem->addServer(192.168.17.114,11211); //存数据 var_dump($mem->set(name,l…...

ELFK之zookeeper+kafka

目录 kafkazookeeper的系统架构 Zookeeper 一、zookeeper概述 二、zookeeper特点 三、zookeeper选举机制 四、应用场景 五、zookeeper实验实例 Kafka 一、概述 为什么需要消息队列(MQ) 使用消息队列的好处 消息队列的两种模式 Kafka 定义 二、Kafka 的特性 三、Ka…...

ECharts

ECharts是一款基于JavaScript的数据可视化图表库&#xff0c;提供直观&#xff0c;生动&#xff0c;可交互&#xff0c;可个性化定制的数据可视化图表。ECharts 提供了常规的折线图、柱状图、散点图、饼图、K线图&#xff0c;用于统计的盒形图&#xff0c;用于地理数据可视化的…...

jsoup框架技术文档--java爬虫--架构体系

阿丹&#xff1a; 在学习以及认知使用一个新技术之前一定要搞清楚有关框架的架构体系。了解一下该技术的底层会对后面编写代码以及寻找报错都是很有用处的&#xff0c;前期做的铺垫多一点&#xff0c;后期开发的时候就很方便。 jsoup框架的关键组件 JSoup框架的关键组件主要包…...

OpenStack创建云主机并连接CRT

文章目录 OpenStackT版创建云主机并连接CRT命令行操作&#xff08;1&#xff09;创建镜像&#xff08;2&#xff09;创建实例&#xff08;3&#xff09;创建网络创建内网创建外网 &#xff08;4&#xff09;创建安全组&#xff08;5&#xff09;创建路由&#xff08;6&#xff…...

linux-sed命令

目录 1.linux-shell sed获取某一段字符串 2.linux-shell shell脚本中 sed -n取出某一行赋给一个变量 3.linux-shell sed查询某一行 1.linux-shell sed获取某一段字符串 如果要获取的是某一段字符串&#xff0c;可以在 sed 命令中使用正则表达式来指定需要获取的字符串。例如…...

Elasticsearch:什么是向量和向量存储数据库,我们为什么关心?

Elasticsearch 从 7.3 版本开始支持向量搜索。从 8.0 开始支持带有 HNSW 的 ANN 向量搜索。目前 Elasticsearch 已经是全球下载量最多的向量数据库。它允许使用密集向量和向量比较来搜索文档。 矢量搜索在人工智能和机器学习领域有许多重要的应用。 有效存储和检索向量的数据库…...

JOSEF约瑟 剩余电流继电器PFR-5 PFE-W-20 国产化改造ZLR-G81 ZCT-45

系列型号&#xff1a; PFR-003剩余电流继电器 PFR-03剩余电流继电器 PFR-5剩余电流继电器 PFR-W-105互感器 PFR-W-140互感器 PFR-W-20互感器 PFR-W-210互感器 PFR-W-30互感器 PFR-W-35互感器 PFR-W-70互感器 一、用途 PFR剩余电流继电器&#xff08;以下简称继电器…...

分别用Python和Go实现对文件夹及其子文件夹里的文件进行批量重命名

文章目录 问题阐述上代码结果如何 问题阐述 最近在继续提高自己的go技术时&#xff0c;从网上一些平台获取到了一些学习资料&#xff0c;然后下载到本地后&#xff0c;文件的命名是真的像衣托答辩&#xff1a; 除了上述的文件&#xff0c;还有一mol多神奇的命名&#xff0c;害…...

redis深度历险 千帆竞发 —— 分布式锁

分布式应用进行逻辑处理时经常会遇到并发问题。 比如一个操作要修改用户的状态&#xff0c;修改状态需要先读出用户的状态&#xff0c;在内存里进行修改&#xff0c;改完了再存回去。如果这样的操作同时进行了&#xff0c;就会出现并发问题&#xff0c;因为读取和保存状态这两个…...

C#根据中文首字母排序

第一种方式&#xff1a; 这种方式会受制于服务器的区域和语言设置。 1.首先添加一个排序类ChineseNameComparer public class ChineseNameComparer : IComparer<string> {public int Compare(string x, string y){if (x null || y null)return 0;var xFirstChar x.Su…...

仪表基础知识培训

压力传感器:E+H PMX5x/FMX5x 一、安装:安装注意事项: 1、水平安装时仪表的呼吸孔(1)需要向下安装,并远离污染物。 2、请勿用坚硬的物体擦拭或接触膜片。 3、请勿安装在水泵的入口和搅拌叶附近 二、供电、接线、信号、:二线制,仪表输出4-20mA 三、量程:设置最大最小量程…...

无涯教程-JavaScript - PI函数

描述 PI函数返回数字3.14159265358979,数学常数pi,精确到15位数字。 语法 PI ()争论 PI函数语法没有参数。 适用性 Excel 2007,Excel 2010,Excel 2013,Excel 2016 Example JavaScript 中的 PI函数 - 无涯教程网无涯教程网提供描述PI函数返回数字3.14159265358979,数学常…...

前端防抖和节流

前端防抖和节流 概述 防抖&#xff1a; 防止抖动&#xff0c;个人字面理解此处防的不是页面的抖动&#xff0c;而是用户手抖。为了防止用户快速且频繁的触发事件而导致多次执行事件函数&#xff0c;这样的场景有很多&#xff0c;比如监听滚动、鼠标移动事件onmousemove、频繁…...

[pai-diffusion]pai的easynlp的clip模型训练

EasyNLP带你玩转CLIP图文检索 - 知乎作者&#xff1a;熊兮、章捷、岑鸣、临在导读随着自媒体的不断发展&#xff0c;多种模态数据例如图像、文本、语音、视频等不断增长&#xff0c;创造了互联网上丰富多彩的世界。为了准确建模用户的多模态内容&#xff0c;跨模态检索是跨模态…...

期权如何交易?期权如何做模拟交易?

买卖期权的第一步就是要有期权账户&#xff0c;国内的期权品种有商品期权和ETF期权以及股指期权&#xff0c;每种的开户方式和要求都不同&#xff0c;下文为大家介绍期权如何交易&#xff1f;期权如何做模拟交易&#xff1f; 一、期权交易需要开立一个期权账户&#xff0c;可以…...

【新书推荐】大模型赛道如何实现华丽的弯道超车 —— 《分布式统一大数据虚拟文件系统 Alluxio原理、技术与实践》

文章目录 大模型赛道如何实现华丽的弯道超车 —— AI/ML训练赋能解决方案01 具备对海量小文件的频繁数据访问的 I/O 效率02 提高 GPU 利用率&#xff0c;降低成本并提高投资回报率03 支持各种存储系统的原生接口04 支持单云、混合云和多云部署01 通过数据抽象化统一数据孤岛02 …...

Calendar对象获取当前周的bug

项目场景&#xff1a; 双周项目管理&#xff0c;需要获取当前周为一年之中的第几周&#xff0c;原先的代码是用Calendar对象&#xff0c;先用setTime&#xff08;&#xff09;把当前时间传入&#xff0c;再用get&#xff08;3&#xff09;获取一年中的第几周 问题描述 实际发…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...