Linux基础——Linux开发工具(gcc/g++,gdb)

前言:在上一篇我们简单介绍了yum,vim的一些常用的指令和模式,现在让我们来进一步了解其他的Linux环境基础开发工具gcc/g++,gdb。


如果对前面yum和vim有什么不懂的建议回顾去回顾上期知识!!!

Linux开发工具(yum, vim)


在这里插入图片描述


首先让我们来初步了解一下本篇的内容:
1. 学习gcc/g++,并能学会如何使用
2. 学习gdb使用,并能进行简单调试

在这里插入图片描述

本篇主要内容:
Linux编译器-gcc/g++使用
Linux调试器-gdb使用

在这里插入图片描述


Linux开发工具

  • 1. Linux编译器-gcc/g++
    • 1.1 gcc/g++的使用方法
    • 1.2 预处理
    • 1.3 编译
    • 1.4 汇编
    • 1.5 链接
  • 2. 函数库
  • 4. Linux调试器-gdb使用
  • 4. 总结


1. Linux编译器-gcc/g++

首先,让我们先来分别了解一下彼此在GNU的作用。

gcc: C语言编译器,只能编译C语言

g++: C++编译器,C/C++都可以编译


gcc和g++在执行编译的时候一般有以下四个步骤:

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

1.1 gcc/g++的使用方法

gcc/g++使用方法如下:

生产的可执行程序a.out
指令:gcc code.c

自定义可执行程序的名字
指令:gcc code.c -o 自定义名称

注意:-o 将处理结果输出到指定文件,该选项后需紧跟输出文件名。


让我们来进行一个简单的测试:

在这里插入图片描述
在这里插入图片描述
如果我们想执行这个程序,我们可以:

指令./a.out

在这里插入图片描述
注意:必须加上.才表示要在当前目录下找可执行文件。

接下来,让我们深入了解gcc/g++的四个步骤:
预处理阶段,编译阶段,汇编阶段,链接阶段


1.2 预处理

在预处理阶段的主要功能包括:宏定义,头文件展开,条件编译,去注释等

我们直接用指令查看一下:
指令:gcc -E test.c -o test.i

  • -E选项的作用是让gcc/g++在预处理结束后停止编译过程, 生成.i文件

在这里插入图片描述

我们直接进入探索。
在这里插入图片描述

可以发现,我们写的代码明明只有几行,但是在test.i中,却多出几百行代码,而这些代码就是预处理阶段展开的头文件,去注释,宏替换,条件编译等操作而出现的。


1.3 编译

在汇编阶段,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查
无误后,gcc 把代码翻译成汇编语言。

简而言之就是:将C语言翻译为汇编代码


我们直接用指令查看一下:
指令:gcc -S test.i -o test.s

  • -S选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码, 生成.s文件

在这里插入图片描述
我们依然直接进入看看
在这里插入图片描述
这里面将代码翻译成了汇编语言

注意:我们可以直接使用指令从.c文件变为.s文件


1.4 汇编

在汇编阶段,就是把编译阶段生成的“.s”文件转成目标文件

将汇编代码变成可重定位二进制文件

我们直接用指令查看一下:
指令:gcc -c test.i -o test.o

  • -c得到汇编代码转化为.o的二进制目标代码,形成.o文件

在这里插入图片描述
我们还是直接进入看看
在这里插入图片描述
我们发现文件里面是乱码,也就是二进制文件

注意:我们可以直接使用指令从.c文件或.i文件变为.o文件


1.5 链接

在完成预处理,编译,汇编后就到了链接阶段,链接的主要任务就是将生成的各个.o文件进行链接,生成可执行程序

.o文件 + 系统库 = 可执行程序

因此这里又涉及到一个重要的概念:函数库

我们直接用指令查看一下:
指令:gcc test.o -o test

若未自定义文件名称,则为a.out

在这里插入图片描述


2. 函数库

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

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

我们可以用指令来查看一个可执行程序依赖的库:
指令:ldd 可执行程序

在这里插入图片描述
因此,test可执行程序所依赖的标准库在路径lib64里有一个文件叫libc.so.6

在这里插入图片描述
所以链接过程就是将.o文件和动/静态库结合的过程

动态库:

优点:省空间,形成的可执行程序体积较小
缺点:有强依赖性,依赖动态库

静态库:

优点:不依赖动态库,可以独立运行
缺点: 体积太大,浪费资源


Linux和windows下的动静态库命名是不太一样的
在这里插入图片描述

我们在编译代码时,默认采用的是动态链接,Linux下绝大多数库都是动态库,如果我们想静态链接:

指令:gcc test.c -static


下面给大家列举出了gcc的常用选项
在这里插入图片描述

4. Linux调试器-gdb使用

首先了解一下程序发布的方式:
程序的发布方式有两种,debug模式和release模式
Linux gcc/g++出来的二进制程序,默认是release模式

  1. debug版本:程序本身会加入调试信息,可以进行调试
  2. release版本:不会添加任何调试信息,是能调试

要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项

在这里插入图片描述因为在debug版本下,会加入调试信息,所以程序的大小比release版本下的大!


我们想进入gdb模式,我们可以:

指令:gdb 文件名

我们想退出gdb模式,我们可以:

指令:ctrl + dquit

下面给大家介绍一下常用的gdb指令:
调试:

r或run:运行程序
n 或 next:单条执行
s或step:进入函数调用
until X行号:跳至X行
finish:执行到当前函数返回,然后挺下来等待命令
continue或c:运行到下一个断点处
set var 变量=x:修改变量的值为x

显示:

list/l n:显示从第n行开始的源代码,接着上次的位置往下列,每次列10行
list/l 函数名:列出某个函数的源代码
print/p 变量:打印变量的值
print/p 表达式:打印表达式的值,通过表达式可以修改变量的值
display 变量:跟踪查看一个变量,每次停下来都显示它的值
undisplay 编号:取消指定编号变量的常显示
info/i locals:查看当前栈帧当中局部变量的值

断点:

break/b n:在第n行设置断点
break 函数名:在某个函数开头设置断点
info break/b:查看已打断点信息
delete/d 编号:删除指定编号的断点
disable 编号:禁用指定编号的断点
enable 编号:启用指定编号的断点

Linux调试器-gdb我们就介绍到这里,调试器需要大家多去使用才能更好的理解与记忆


4. 总结

在理解完本篇之后希望各位都能理解gcc/g++的四个步骤,gdb的简单使用方法!
在这里插入图片描述
谢谢大家支持本篇到这里就结束了
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【问题实操】银河麒麟高级服务器操作系统实例,CPU软锁报错触发宕机

1.服务器环境以及配置 处理器: Kunpeng 920 内存: 256G DDR4 整机类型/架构: TaiShan 200 (Model 2280) 内核版本 4.19.90-23.8.v2101.ky10.aarch64 2.问题现象描述 两台搭载麒麟v10 sp1的机器均在系统CPU软锁报错时,触…

sCrypt全新上线RUNES功能

sCrypt智能合约平台全新上线一键etch/mint RUNES功能! 请访问 https://runes.scrypt.io/ 或点击阅读原文体验! 关于sCrypt sCrypt是BSV区块链上的一种智能合约高级语言。比特币使用基于堆栈的Script语言来支持智能合约,但是用原生Script编…

JavaScript创建和填充数组的更多方法

空数组fill()方法创建并填充数组 ● 我们之前创建数组的方式都是手动去创建去一个数据,例如 console.log([1, 2, 3, 4, 5, 6, 7]);● 当然我们也可以使用Array对象来构造数组 console.log([1, 2, 3, 4, 5, 6, 7]); console.log(new Array(1, 2, 3, 4, 5, 6, 7));…

​「Python大数据」词频数据渲染词云图导出HTML

前言 本文主要介绍通过python实现数据聚类、脚本开发、办公自动化。词频数据渲染词云图导出HTML。 一、业务逻辑 读取voc数据采集的数据批处理,使用jieba进行分词,去除停用词词频数据渲染词云图将可视化结果保存到HTML文件中二、具体产出 三、执行脚本 python wordCloud.p…

2024最新智慧医疗智慧医院大数据展示,医院数据采集概况、医院指标分析、医院就诊趋势分析等。源代码免费下载。

系列文章目录 【复制就能用1】2分钟玩转轮播图,unslider的详细用法 【复制就能用2】css实现转动的大风车,效果很不错。 【复制就能用3】2分钟自己写小游戏:剪刀石头布小游戏、扫雷游戏、五子棋小游戏 【复制就能用4】2024最新智慧医疗智慧医院大数据…

信息系统项目管理师0072:集成基础(5信息系统工程—5.3系统集成—5.3.1集成基础)

点击查看专栏目录 文章目录 5.3系统集成5.3.1集成基础5.3系统集成 随着信息技术的发展,系统集成逐步成为信息系统实施中一项重要的工作。此处的系统集成概念专指计算机系统的集成,包括计算机硬件平台、网络系统、系统软件、工具软件、应用软件的集成,围绕这些系统的相应咨询…

Unity读书系列《Unity高级编程:主程手记》——架构

文章目录 前言一、架构的意义1、承载力2、可扩展性3、易用性4、可伸缩性5、容错性以及错误的感知力 二、软件架构的思维方式二、构建Unity项目1、前端和后端架构之间2、培养架构设计思路3、Unity项目的分层设计 总结 前言 这篇文章是《Unity高级编程:主程手记》的第…

maldev tricks在注册表中存储 payload

简介 注册表是 Windows 操作系统中一个重要的数据库,它包含 Windows 操作系统和应用程序的重要设置和选项。由于注册表的功能非常强大,因此注册表对于恶意程序来说是非常有利用价值的。 在 windows 注册表中存储二进制数据,这是一种常见的技…

java中的泛型(二)——泛型接口以及泛型方法

在上一篇文章中&#xff0c;简要地对泛型的概念以及泛型类的使用进行了说明。除了在泛型类之外&#xff0c;泛型还可以在接口和方法中使用。 泛型接口 对于泛型接口&#xff0c;它的声明方式为: public interface 接口名 <泛型>{泛型定义的抽象方法}。这个声明方式和泛型…

[最新]CentOS7设置开机自启动Hadoop集群

安装好Hadoop后我们可以使用开机自启动的方式&#xff0c;节约敲命令的时间。注意是centOS7版本!!!和centOS6版本区别非常大!!! 1、切换到系统目录 [rootmaster ~]# cd /etc/systemd [rootmaster systemd]# ll total 32 -rw-r--r-- 1 root root 720 Jun 30 23:11 bootcha…

arcgis js 4.x加载SceneLayer并实现基于属性查询定位及高亮

一、代码 <!DOCTYPE html> <html> <head><meta charset"utf-8" /><meta name"viewport" content"widthdevice-width, initial-scale1,maximum-scale1,user-scalableno"><title></title><link rel…

2周速通春招联想Lenovo机器学习算法岗-面经篇

联想校招官网-联想校园招聘 不得不夸一下联想的效率&#xff0c;笔试到offer只用了两周。 先说教育背景&#xff1a;河南科技大学 本科&#xff0c;南京邮电大学 硕士。 时间线 4.x投简历&#xff0c;我一志愿是天津的岗位&#xff0c;想着天津新盖了厂房&#xff0c;容易进一…