【Linux】Linux编译器-gcc/g++使用

news2024/11/24 4:21:16

大家好我是沐曦希💕

文章目录

  • 1.背景知识
    • 1.1 预处理
    • 1.2 编译(生成汇编)
    • 1.3 汇编(生成机器可识别代码)
    • 1.4 链接接(生成可执行文件或库文件)
    • 1.5 习题
    • 习题一
    • 习题二
  • 2.函数库
    • 2.1 动态库
    • 2.2 静态库
  • 3.g++的基本使用
  • 4.gcc选项
  • 4.写在最后

1.背景知识

1.1 预处理

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

预处理时候编译器会把头文件展开,去掉注释,宏替换,条件编译等
选项 -E 是进行程序的翻译,预处理做完就停止编译过程。
选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序
头文件展开,去注释,宏替换,条件编译

gcc -E test.c -o test.i

-E:从现在开始,进行程序的翻译,当你将预处理做完,就停下来

-o:指明形成的临时文件名称(.i)
在这里插入图片描述
此时生成test.i,我们用vim进入test.c,在利用底行模式vs test.i:
在这里插入图片描述
可以看到预处理把头文件展开了,去注释,宏替换,条件编译。(此时临时文件还是c语言)
在这里插入图片描述
可以向编译器传参来保证宏在命令行中定义

1.2 编译(生成汇编)

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

把C转换成汇编语言:
在这里插入图片描述
S:从现在开始,进行程序的翻译,做完编译工作,变成汇编之后,就停下来

用vim打开test.s我们就可以看到汇编代码了:
在这里插入图片描述

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

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

注意的是:此时生成的临时文件不是可以执行大的,是二进制目标文件,不能被执行,因为少了链接。
-c 从现在开始,进程程序的翻译,做完汇编工作变成可重定向目标二进制,就停下来
用vim打开test.o,但是我们根本看不懂:
在这里插入图片描述
再输入指令od test.o(以二进制形式打开该文件):
在这里插入图片描述

1.4 链接接(生成可执行文件或库文件)

链接的过程就是把写的代码和C标准库中的代码合起来

在成功编译之后,就进入了链接阶段。
实例: gcc hello.o –o hello

-o 链接的过程,形成可执行程序,可执行的二进制程序(库+你的代码)
在这里插入图片描述

1.5 习题

习题一

1.在编译过程中,产生parse tree的过程是哪个阶段?
A.语法分析
B.语义分析阶段
C.词法分析
D.目标代码生成阶段

答案:A

  • 编译过程为 扫描程序–>语法分析–>语义分析–>源代码优化–>代码生成器–>目标代码优化;
  • 扫描程序进行词法分析,从左向右,从上往下扫描源程序字符,识别出各个单词,确定单词类型
  • 语法分析是根据语法规则,将输入的语句构建出分析树,或者语法树,也就是我们答案中提到的分析树parse tree或者语法树syntax tree
  • 语义分析是根据上下文分析函数返回值类型是否对应这种语义检测,可以理解语法分析就是描述一个句子主宾谓是否符合规则,而语义用于检测句子的意思是否是正确的
  • 目标代码生成指的是,把中间代码变换成为特定机器上的低级语言代码。
  • 根据以上各个阶段的理解,可以分析出正确选项为A选项。

习题二

2.程序的完整编译过程分为是:预处理,编译,汇编等,
如下关于编译阶段的编译优化的说法中不正确的是
A.死代码删除指的是编译过程直接抛弃掉被注释的代码
B.函数内联可以避免函数调用中压栈和退栈的开销
C.for循环的循环控制变量通常很适合调度到寄存器访问
D.强度削弱是指执行时间较短的指令等价的替代执行时间较长的指令

答案:A

  • 死代码删除是编译最优化技术,指的是移除根本执行不到的代码,或者对程序运行结果没有影响的代码,而并不是删除被注释的代码,因此A选项错误
  • 内联函数,也叫编译时期展开函数, 指的是建议编译器将内联函数体插入并取代每一处调用函数的地方,从而节省函数调用带来的成本,使用方式类似于宏,但是与宏不同的是内联函数拥有参数类型的校验,以及调试信息,而宏只是文本替换而已。因此B选项正确
  • for循环的循环控制变量,通常被cpu访问频繁,因此如果调度到寄存器中进行访问则不用每次从内存中取出数据,可以提高访问效率,因此C选项正确
  • 强度削弱是指执行时间较短的指令等价的替代执行时间较长的指令,比如 num % 128 与 num & 127 相较,则明显&127更加轻量, 故D也是正确的

2.函数库

注意:我们自己写的代码和库是两码事。
链接的本质就是我们调用库函数的时候和标准库,如何关联的问题。

C标准库是别人已经给我们准备好的,直接使用,我们所有使用库中函数的代码(比如printf)其中我们自己只写了该函数的调用,没有对应的实现,只有当链接的时候,对应的实现,才和我们的代码关联起来.

我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?
最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用

  • 验证是动态链接还是静态链接

第一步先生成可执行文件

gcc test.o -o mytest

在这里插入图片描述
第二步查看可执行文件什么方式链接的

file mytest

在这里插入图片描述
dynamically linked 是动态链接

第三步查看可执行文件的动态库:
在这里插入图片描述
其中libc.so.6就是动态库。

函数库一般分为静态库和动态库两种

2.1 动态库

动态库在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件。
形成的可执行程序小(节省资源,内存,磁盘,网络)

2.2 静态库

静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a
不受库升级或者被删除的影响,线程的可执行程序体积太大,网络、磁盘、内存占用过大

静态库是将C标准库拷贝一份放在你程序里面,链接不是产生关联,而是在我们程序内部要用的方法,给我的程序拷贝一份,就完成了静态链接。
优势:不受库升级或者库被删除的影响。
缺点:形成的可执行程序体积过大–网络,磁盘,内存

去掉前缀lib去掉后缀.so剩下的就是库名称
对于上面的libc.so.6去掉后就剩下C,所以这个库是C标准库(动态库)
这个库的位置:

ll /lib64/libc.so.6

在这里插入图片描述
Linux下默认形成可执行程序,默认使用的是动态库 /lib64/libc-2.17.so
在这里插入图片描述

  • 生成静态链接
    生成可执行程序的命令后面要加上-static
gcc test.c -o mytest.s -static

在这里插入图片描述
查看链接方式:
在这里插入图片描述
statically linked 是静态链接,其中ldd命令只能查看动态链接的可执行程序。

我们不能删掉系统中的C动态库,因为Linux的命令都是动态链接的,不要删除C动态库!!!用这个库的程序非常多,但是库只有一份,所有用C语言写的程序,不会出现重复的库代码。
在这里插入图片描述
那么动态库相当于一个共享库,以后我们下载一个c写的程序,不用下C标准库。
静态链接拷贝的不是.so内部的代码,拷贝的是系统里必须存在.a结尾的静态库。/lib64/lib.a静态库。

动态链接只能找动态库,静态链接只能找静态库(一般而言,系统会自动携带动态库,因为系统运行需要动态库。静态库如果不存在,需要自己安装!)

  • 手动安装静态库

查看libc.a是否已经安装:

sudo find / -name 'libc.a'

在这里插入图片描述
安装:

sudo yum install -y glibc-static

在这里插入图片描述

3.g++的基本使用

  • 安装g++
sudo yum install -y gcc-c++
  • 安装C++静态库
sudo yum install -y libstdc++-static

当然了C++也有相应的静态库和动态库
在这里插入图片描述
在这里插入图片描述

4.gcc选项

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

4.写在最后

系统本身为了支持我们编程,个我们提供了标准库的.h(告诉我们怎么用)
标准的动静态库.so/.a(告诉我们方法实现)
我们的程序通过使用包含头文件,然后链接别人的库来实现将我的代码+库的代码形成可执行程序!!!
我的代码+库的代码==可执行程序
另外,windows下的原理是一样的默认形成可执行动态链接,动态:.dll,静态:.lib

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

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

相关文章

数据结构之二叉树

数据结构之二叉树什么是二叉树二叉树的特殊类型二叉树的遍历方式二叉树的叶子结点求法二叉树的高度求法什么是二叉树 二叉树(Binary tree)是树形结构的一个重要数据类型,想要成为二叉树必须满足两个条件。1、本身是有序树。2、树中包含的各个…

【小程序】导航栏和内容页面联动效果实现

💭💭 ✨: 微信小程序导航栏和页面联动   💟:东非不开森的主页   💜: 因为很多东西来不及去做去看可是时间很快总是赶不上,所以要去成长呀💜💜   🌸: 如有错…

React—— HelloWorld

React 学习笔记Hello WorldJSX (JavaScript XML) 语法规则JavaScript 语法函数组件、类组件 & 属性 props组合组件生命周期函数 & 状态 state事件处理refs受控组件、非受控组件 & 高阶函数、函数的柯里化npm参考Hello World <!DOCTYPE html> <html lang&…

Request请求转发与Respones请求重定向有什么区别?

目录&#xff1a; 1.Request请求转发 2.Respones请求重定向 3.关于转发和重定向的路径问题 1.Request请求转发 请求转发(forward)是一种在服务器内部的资源跳转方式。 (1)浏览器发送请求给服务器&#xff0c;服务器中对应的资源A接收到请求 (2)资源A处理完请求后将请求发…

在html中使用js实现图片的无缝滚动(四种状态)

文章目录js原理实施任务1.从左往右无缝滚动代码示例运行效果2.从右往左无缝滚动代码示例运行效果3.从上往下无缝滚动代码示例运行效果4.从下往上无缝滚动代码示例运行效果js原理 获取整个ul和ul下面的所有li&#xff0c; 把ul里面的li内容添加一份&#xff0c;因为需要完成图片…

【加油站会员管理小程序】01需求分析

随着这两年微搭产品的迭代,目前组件基本够用,像常用的支付这种功能也是有的,因此我们就可以结合现有功能来完成一个实际使用的小程序的开发。 我们本次的实战课,是以加油站的业务场景为出发点,涵盖会员的开通、充值、消费、积分兑换等常用场景。结合实战案例,我们完整的…

12月2日:thinkphp中的链式操作

补充内容&#xff1a; 今天我们就来聊聊limit和page的区别以及group by需要注意的点&#xff0c;where和having的区别 limit和page 区别 Limit 限制查询数量&#xff0c;在进行分页查询的时候用的最多&#xff0c;但是limit在查询限制中的索引值是从0开始的&#xff0c;lim…

基于Java+Springboot+Vue+elememt疫情返乡人员管控系统设计实现

博主介绍&#xff1a;✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取联系&#x1f345;精彩专栏推荐订阅收藏&#x1f447;&…

一文搞懂如何学习Android内部命令行工具集合

目录 1.安卓命令工具集 2.命令如何使用&#xff08;举例&#xff09; 2.1 am命令使用 2.2 dumpsys 命令使用 2.3 wm命令用法 2.4 rm命令的用法 2.5 logcat 命令的用法 2.6 cat 命令的用法 3.个人如何学习 3.1 推荐学习方法一 3.2 方法二 1.安卓命令工具集 安卓支持…

JMeter入门教程(7) --思考时间

1.人物背景 在JMeter脚本中&#xff0c;思考时间使用定时器模拟实现的 2.任务目标 掌握基于JMeter性能测试脚本开发——思考时间 3.任务实操 3.1 固定定时器 右击取样器&#xff0c;选择“添加 > 定时器 > 固定定时器&#xff0c;如图示&#xff1a; 2.固定定时器页…

手机无线耳机什么牌子的好用?2022好用的无线蓝牙耳机排行榜

现如今的蓝牙耳机市场中有着多种机型&#xff0c;不同功能&#xff0c;不同价格的蓝牙耳机数不胜数&#xff0c;一部手机、一副耳机似乎已经成为了人们外出的搭配。那么手机无线耳机什么牌子的好用呢&#xff1f;下面我来给大家推荐几款好用的无线蓝牙耳机&#xff0c;大家可以…

团队协作利器----API接口Eolink

本文目录&#xff1a;一、初识Eolink1.什么是Eolink2.我与Eolink的故事二、Eolink突出特点----团队协作协同工作分享协作支持所有类型API文档、测试方便导出接口文档方便查看历史记录三、Eolink优势总结前言&#xff1a; hello大家好&#xff0c;我是Dream&#xff0c;在我们的…

安卓中adb命令工作的底层原理及使用举例

目录 1. adb安卓调试桥 2.adb的组成 3.adb命令的使用举例: 3.1什么是应用包?什么是应用界面? 3.2 adb 命令如何获取应用应用包名和应用界面名? 1. adb安卓调试桥 adb的全称为Android Debug Bridge&#xff0c;就是起到调试桥的作用。通过adb我们可以在Eclipse中方便通过…

c程序从编译开始到运行结束的过程

重温c语言 我们在linux平台下建立一个a.c文件,程序很简单&#xff0c;显示输出Please input your name:&#xff0c;然后让我们输入名字&#xff0c;最后调用了一个子函数输出hello,我们的名字 #include<stdio.h>void hello(char * name);int main(){char name[16]{0};p…

(4E)-TCO-PEG4-acid,1802913-21-8物理性质分享

(4E)-TCO-PEG4-acid物理数据&#xff1a; CAS&#xff1a;1802913-21-8| 中文名&#xff1a;(4E)-反式环辛烯-四聚乙二醇-羧酸 | 英文名&#xff1a; (4E)-TCO-PEG4-acid 结构式&#xff1a; 英文别名&#xff1a; (4E)-TCO-PEG4-COOH TCO4-PEG4-COOH 中文别名&#xff1a…

【Flink】一文解析Flink如何实现状态管理和容错机制

文章目录一 Flink中的状态管理1 有状态的算子和应用程序&#xff08;1&#xff09;算子状态&#xff08;operator state&#xff09;&#xff08;2&#xff09;键控状态&#xff08;keyed state&#xff09;2 状态后端3 选择一个状态后端二 Flink中的容错机制1 一致性检查点&am…

自建传奇2服务器,分享自己架设传奇服务器的详细介绍

我们在经历了太多的传奇私服之后就会有人想要自己搞一个来看看&#xff0c;其实有这样想法的人其实还是很多的&#xff0c;毕竟当一个玩家总没有当一个GM来的实在。于是就有人选择自己去架设传奇私服的服务器&#xff0c;而这个时候我们的信息就能够给这些想要自己当GM的人一个…

uniapp多端问题总结

页面跳转相关 1、页面跳转传参报错 问题&#xff1a; 小程序报错 SyntaxError: Unexpected end of JSON inputat JSON.parse () 原因&#xff1a;是由于JSON.parse无法识别某些url中的特殊字符比如&等特殊符号。解决办法&#xff1a; 原来代码&#xff1a; // 跳转所属专…

【Linux】—一文掌握Linux基本命令(上)

目录lspwdcdtouchmkdirrmdir与rmmantree 的安装cpmvnano的安装catls 语法&#xff1a; ls [选项][目录或文件] 功能&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息。 常用拓展选项&#xff1a; -a 列出…

J-Tech Talk|以型搜型:3D模型表征助力3D神经搜索!

以型搜型指的是 以3D模型搜索3D模型&#xff0c;在对 3D 物体进行模型表征后&#xff0c;通过最近邻搜索得到与之类似的3D物体的结果。Executor-3d-encoder 项目集成了若干个 3D 物体表征模型&#xff0c;开发者可以很方便地对不同的模型进行统一配置、训练和微调。12 月 6 日晚…