【Hello Linux】Linux工具介绍 (gcc/g++ gdb)

news2024/12/25 23:57:29

作者:@小萌新
专栏:@Linux
作者简介:大二学生 希望能和大家一起进步!
本篇博客简介:介绍Linux的常用工具gcc/g++ 以及gbd

Linux工具介绍

  • gcc / g++
    • gcc / g++的作用
    • 为什么语言要经过这四步才能变为可执行指令
    • gcc / g++语法
    • 预处理
    • 编译
    • 汇编
    • 链接
    • 动态库和静态库
  • gdb
    • debug和release
    • gdb指令

gcc / g++

gcc / g++的作用

gcc和g++分别是GNU的C和C++的编译器

我们都知道语言从源文件到可执行指令要分为以下四个步骤

  1. 预处理 (去除注释 头文件展开 宏替换 条件编译)
  2. 编译 (将c/c++ 代码翻译成汇编代码)
  3. 汇编 (将汇编代码转化为二进制语言)
  4. 链接 (将汇编过程产生的二进制语言进行连接)

为什么语言要经过这四步才能变为可执行指令

我们在上一些语言课的时候 一些学校里的教授可能跟我们讲过它们那个年代是怎么进行编程的

打孔编程

在这里插入图片描述

不过后面人们发现 这种打孔编程的指令很难让人记住并且效率极其低下 于是乎人们便发明出了汇编语言

从此之后我们变开始用汇编语言进行代码编程

汇编的语言的编译过程是这样子的

在这里插入图片描述

之后呢随着时代的进步 人们认为汇编语言还是太过复杂了 于是乎c语言就被发明出来了

之后c语言想要变成二进制文件就有两条路

在这里插入图片描述

c语言是直接变成二进制文件简单一点还是先变成汇编语言再变成二进制文件简单一点?

很显然 如果直接从c语言直接变成二进制文件的话等于前面几十年的努力全部被白费了

但是如果先变成汇编语言的话就简单很多 而且汇编语言变成二进制文件也是可以借鉴之前的经验的

在这里插入图片描述

当然由于C语言的编写中可能会存在大量的注释以及头文件的展开等

所以我们还需要预处理这一步骤将注释全部清除 将头文件展开

gcc / g++语法

我们常用的gcc语法是这样子的

gcc/g++ 选项 文件

下面是gcc g++的一些选项 其中前面七个选择特别重要 需要记住

  1. -E 只进行预处理 不生成文件 你需要把他重定向到一个输出文件里面(否则将把预处理后的结果打印到屏幕上)
  2. -S 编译到汇编语言
  3. -c 编译到目标代码(二进制文件)
  4. -o 将处理结果输出到指定文件 该选项后需紧跟输出文件名
  5. -static 此选项对生成的文件采用静态链接
  6. -shared 此选项将尽量使用动态库,生成文件较小
  7. -g 生成调试信息(若不携带该选项则默认生成release版本)
  8. -w 不生成任何警告信息
  9. Wall 生成所有警告信息
  10. -O0/-O1/-O2/-O3 编译器优化选项的四个级别 -O0表示没有优化 -O1为缺省值 -O3优化级别最高

预处理

预处理的作用包括下面四个

  • 去除注释
  • 头文件展开
  • 宏替换
  • 条件编译

接下来我们敲出下面的代码 让预处理之后的文件输出到test.i文件中

    gcc -E test.c -o test.i

我们分别在C文件中添加上注释 头文件 宏替换和条件编译语句

在这里插入图片描述
我们可以发现经过预处理之后代码膨胀到了800多行 这是因为头文件展开的效果

条件编译和宏替换是同步进行的 因为N是100 非0表示真 所以执行的是

hello vim!

最后我们可以发现注释也全部消除了
在这里插入图片描述

编译

编译的作用包括下面两个

代码如下

  gcc -S test.i -o test.s
  • 检查代码语法是否有错误
  • 将代码翻译成汇编语言

在这里插入图片描述
我们可以发现代码都变成汇编语言了

当然要是我们编写的代码中有一些语法的错误的话 在编译这一步就会停止

汇编

汇编的作用主要有一个

  • 将汇编语言翻译成二进制语言

代码如下

  gcc -c test.s -o test.o

在这里插入图片描述
我们可以发现这里变成了我们看不懂的乱码 实际上这里就是二进制语言

链接

链接的作用主要有一个

  • 将生成的 .o文件(二进制文件) 进行链接

代码如下

  gcc test.o -o testhv

在这里插入图片描述
之后我们便得到了一个可执行文件了

运行它 就能发现屏幕输出 hello vim!

在这里插入图片描述

动态库和静态库

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

  • 静态库是指编译链接时 把库文件的代码全部加入到可执行文件当中 因此生成的文件比较大 但在运行时也就不再需要库文件了 静态库一般以.a为后缀
  • 动态库与之相反 在编译链接时并没有把库文件的代码加入到可执行文件当中 而是在程序运行时由链接文件加载库 这样可以节省系统的开销 动态库一般以.so为后缀

映射到我们现实生活中

在这里插入图片描述
动态库就是网吧 你在宿舍里面写作业 当你遇到不会的题目的时候就回去网吧搜索 这道题目应该怎么做

而静态库就是你自己买了个电脑 以后遇到不会的题目就可以在自己宿舍查了

动态链接:

  • 优点:省空间 bin体积小 加载速度快
  • 缺点:依赖动态库 程序可移植性较差

静态链接:

  • 优点:不依赖第三方库 程序的可移植性较高
  • 缺点:浪费空间

我们的gcc/g++编译器默认使用的是动态链接

我们可以使用file指令查看

在这里插入图片描述
我们还可以使用ldd指令来查看可执行文件所依赖的库

在这里插入图片描述
其中的 /lib64/libc.so.6就是c语言标准库

我们可以使用 -static指令来强制进行静态链接

如果我们编译的过程中出现这个错误

/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status

这是由于我们的云服务器中没有安装静态库引起的

这个时候我们只需要下载一下静态库就可以了

下载指令如下

sudo yum install -y glibc-static libstdc++-static

这个时候我们使用ldd指令就可以发现
在这里插入图片描述

此外 因为静态链接里面包含了整个静态库 所以说代码会膨胀很多倍

在这里插入图片描述
这也刚好证明了动态链接的优点 省空间

gdb

debug和release

我们在C语言的学习阶段就知道了程序有两种发布版本

分别是 release 和 debug

  • debug版本:程序本身会被加入更多的调试信息 以便于进行调试
  • release版本:不会添加任何调试信息 是不可调试的

我们在linux中默认生成的文件都是release版本的 是不可以使用gbd调试的

如果我们想要它可被调试则需加入debug信息

具体指令如下

  gcc test.c -o testhv_g -g

在这里插入图片描述

我们可以发现debug版本的代码确实比release代码大一点 这是因为多了调试信息

gdb指令

【进入gdb】

  • gdb 文件名

【调试】

  • 「run/r」:运行代码(启动调试)
  • 「next/n」:逐过程调试
  • 「step/s」:逐语句调试
  • 「until 行号」:跳转至指定行
  • 「finish」:执行完当前正在调用的函数后停下来
  • 「continue/c」:运行到下一个断点处
  • 「set var 变量=x」:修改变量的值为x (不常用)

【显示】

  • 「list/l n」:显示从第n行开始的源代码 每次显示10行 若n未给出则默认从上次的位置往下显示
  • 「list/l 函数名」:显示该函数的源代码
  • 「print/p 变量」:打印变量的值
  • 「print/p &变量」:打印变量的地址
  • 「print/p 表达式」:打印表达式的值 通过表达式可以修改变量的值
  • 「display 变量」:将变量加入常显示(每次停下来都显示它的值
  • 「display &变量」:将变量的地址加入常显示
  • 「undisplay 编号」:取消指定编号变量的常显示
  • 「bt」:查看各级函数调用及参数
  • 「info/i locals」:查看当前栈帧当中局部变量的值

【断点】

  • 「break/b n」:在第n行设置断点
  • 「break/b 函数名」:在某函数体内第一行设置断点
  • 「info breakpoint/b」:查看已打断点信息
  • 「delete/d 编号」:删除指定编号的断点
  • 「disable 编号」:禁用指定编号的断点
  • 「enable 编号」:启用指定编号的断点

【退出gdb】

  • 「quit/q」:退出gdb

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

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

相关文章

机器学习强基计划8-1:图解主成分分析PCA算法(附Python实现)

目录0 写在前面1 为什么要降维?2 主成分分析原理3 PCA与SVD的联系4 Python实现0 写在前面 机器学习强基计划聚焦深度和广度,加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的数学原理;“广”在分析多个机器学习模型&#xf…

MATLAB | 情人节来绘制更立体的玫瑰花吧

又是一年情人节,今年带来一款更有立体感的玫瑰: 曲面的函数表达式来自: http://www.bugman123.com/Math/index.html 这个网站,上面还有很多其他帅气的玩意。 基础绘制 xlinspace(0,1,300); thetalinspace(-2*pi,15*pi,300); [x,theta]meshg…

【历史上的今天】2 月 14 日:第一台通用计算机面世;IBM 成立;Julia 公开发布

整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来。 今天是 2023 年 2 月 14 日,在 1819 年的今天,打字机和第一台 QWERTY 布局键盘的发明者克里斯托弗肖尔斯(Christopher Sholes)出…

API文档自动生成工具

一、参考资料 从Python源码注释,自动生成API文档 二、问题引入 不管是开源还是闭源,要让所有人都能读懂你的代码这太难了,所以文档是很重要的。大部分情况,我们不希望维护一份代码再加上一份文档,这样做很容易造成文…

Springboot扩展点之InitializingBean

前言InitializingBean这个扩展点,其实在Springboot扩展点之BeanPostProcessor中已经简单有所涉及,而这篇文章的将重点分析其功能特性、实现方式和工作原理。功能特性1、Spring中提供了InitializingBean接口,帮助用户实现一些自定义的初始化操…

为什么学了模数电还是看不懂较复杂的电路图

看懂电路并不难。 (1) 首先要摆正心态,不要看到错综复杂的电路图就一脸懵逼,不知所错。你要明白,再复杂的电路也是由一个个的基本电路拼装出来的。 (2) 基础知识当然是少不了的,常用的基本电路结构搞搞清楚。 (3) 分析电路之前先要…

Unity通俗易懂的讲解PPU(Pixel Per Unit)与Camera Size

目录 前言 Unity的一个单位 Camera Size Pixel Per Unit的具体含义 前言 unity 2d中的sprite ,具有一个参数:Pixel Per Unit 初学者往往不知道这个代表什么意思,如何理解,怎么设置,这个在unity的美术素材的使用也…

DynamicPDF HTML Converter for .NET 1.9 Crack

.NET HTML 到 PDF 转换库,快速将 HTML 转换为 PDF,转换为文件或字节数组,多线程性能 DynamicPDF Converter for .NET is a .NET API that allows developers to dynamically convert many common file formats to PDF documents in real-time. Converter supports converting …

使用Cifar10训练DenseNet121

DenseNet默认就是DenseNet-BC, 相对于resnet,densenet权重参数更少,鲁棒性更强. 0、下载数据集:Cifar-10在同级文件data下 预训练权重: densenet121: https://download.pytorch.org/models/densenet121-a639ec97.pth…

C++ 之基本数据类型(整型、布尔型及字符型)

文章目录参考描述数据类型整形有符号无符号规则sizeof 运算符进制cout 的自动转换(进制)后缀验证溢出主动权溢出布尔型变量判断结果字符型ASCII细节范围参考 项目描述菜鸟教程数据类型搜索引擎GoogleC Primer Plus (第六版)中文版…

深度学习目标检测_YOLOV4超详细解读

文章目录一. 前言yolov4的创新点2.1 输入端的创新2.1.1数据增强2.1.2自对抗训练(SAT)2.2BackBone创新Dropblock标签平滑损失函数IOU LossGIOU LossDIOU LossCIOU Loss一. 前言 作者AlexeyAB大神! YOLOv4 拥有43.5%mAP65FPS ,达到…

C语言(利用函数将字符串转换为数字和数子转换字符串)

目录 1.atoi(字符串转换为int类型) 2.atof(字符串转换为float类型) 3.atol(字符串转换为long类型) 4.strtol(字符串转换为long类型,但可以选择转换的进制,以及标记结束字符地址) 5.strtod(字符串转换为double类型,可以标记结束字符地址) 6.整数和浮点数转换为…

项目进度经常超时怎么办?项目经理如何有效管理项

当项目延期,我们要先找根因,再根据根因制定具体针对性措施。如果是故障,第一时间是以修复问题为主,然后去找原因,最终给出对应的措施。 对于项目进度,那首先要去了解延期的原因,是计划制定的不…

vite 项目切换不同依赖项的分支,运行加载缓慢问题的解决方案(Pre-bundling dependencies)

前言 当我们在首次使用 yarn dev 命令启动 vite 时,或者 切换分支,依赖项发生变化时 会发现项目启动时相当的慢,大概要十几分钟,而且控制台终端打印了如下信息: Pre-bundling dependencies: this will be run only …

vivo官网App模块化开发方案-ModularDevTool

作者:vivo 互联网客户端团队- Wang Zhenyu 本文主要讲述了Android客户端模块化开发的痛点及解决方案,详细讲解了方案的实现思路和具体实现方法。 说明:本工具基于vivo互联网客户端团队内部开源的编译管理工具开发。 一、背景 现在客户端的业…

【Jqgrid分页勾选保存】三步实现表格分页勾选(取消勾选)保存(附源码)

目录1、创建临时存储数组,初始化赋值2、单行选中与取消,调整数组3、全选与取消全选,调整数组4、输出数组保存5、片尾彩蛋【写在前面】表格可以说是在我们的web页面中是最常见的,之前我们介绍过layui表格翻页勾选的实现过程&#x…

到2030年,边缘计算潜在市场将增长至4450亿美元!

国际电信咨询公司STL Partners近日出了一份边缘计算关键数据统计,重点介绍了九项边缘计算统计数据,边小缘着手翻译了一下这些数据,这些数据预测显示了边缘计算市场的增长潜力,以及边缘部署数量最多的垂直行业和地区。1.到2030年&a…

java Spring aop入门准备工作

首先 Spring 框架一般都是基于 Aspect]实现 AOP 操作 然后就会带出问题 什么是 Aspect 首先 Aspect并不属于Spring 他是一个单独的AOP框架 离开Spring他也能单独运行 但在Spring开发中 我们常用他来配合Spring完成AOP操作 所以说 我们是要 基于Aspect去配合Spring完成AOP操作…

压力应变电桥信号隔离放大变送器差分输入0-±10mV/0-±20mV转0-20mA/0-10v

概述:DIN11 IPO 压力应变桥信号处理系列隔离放大器是一种将差分输入信号隔离放大、转换成按比例输出的直流信号导轨安装变送模块。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等行业。此系列模块内部嵌入了一个高效微功率的电源,向输入…

ChatGPT入门案例|商务智能对话客服(二)

ChatGPT是人工智能研究实验室OpenAI新推出的一种人工智能技术驱动的自然语言处理工具,使用了Transformer神经网络架构,也是GPT-3.5架构,这是一种用于处理序列数据的模型,拥有语言理解和文本生成能力,尤其是它会通过连接…