目录
Ⅰ. Linux 软件包管理器 yum
一、yum 背景知识
二、yum 的基本使用
1、查看软件包
2、软件包名称构成
3、安装软件
4、卸载软件
Ⅱ.vim编辑器
一、认识vim
1、vim概念
2、模式及其切换
二、vim使用
1、vim的指令(重要)
命令模式
插入模式
底行模式
2、vim配置
Ⅲ.gcc/g++编译器
1.程序的编译和运行
2.使用gcc工具完成操作
(1)预处理
(2)编译(生成汇编)
(3)汇编(生成机器码)
(4)连接(生成可执行文件或库文件)
3.函数库
系统函数库
动态链接和静态链接
Ⅳ.项目自动化构建工具Make/Makefile
1.Make/Makefile的介绍
2.Make/Makefile的简单使用
Ⅴ.gdb调试代码
1.什么是gdb
2.debug和release
3.gdb调试操作
(1)进入调试
(2)显示源代码
(3)断点的添加、删除和信息显示
(4)run运行调试程序与continue继续运行
(6)查看某个变量的值
(7)退出gdb
4.其他命令
Ⅰ. Linux 软件包管理器 yum
一、yum 背景知识
- 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序.
- 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安 装程序)放在一个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装.
- 软件包和软件包管理器, 就好比 "App" 和 "应用商店" 这样的关系.
- yum(Yellow dog Updater, Modifified)是Linux下非常常用的一种包管理器. 主要应用在Fedora, RedHat, Centos等发行版上.
通俗易懂的讲,yum就如同手机上的应用商店,想下载软件包就通过yum
值得注意的是:
如果你使用的是云服务器,那么 yum 源一般都是配置好的,如果你使用的是虚拟机,你需要打开 CentOS-Base.repo 查看里面的链接是否是国内的链接,如果不是,就需要自己手动配置,配置的方法网上很多,直接搜索对应的Linux发行版即可。
在Linux中,yum 源配置文件是存在于 /etc/yum.repos.d/ 目录下的 CentOS-Base.repo 文件
二、yum 的基本使用
1、查看软件包
我们可以通过 yum list 命令列举出当前一共有哪些软件包可供安装(那个显示可安装程序的动图太大了传不上来……)
但软件包的数目太多, 所以我们一般使用 grep 命令来筛选出我们需要的包,比如找到有关键词python的软件包
yum list | grep python.x86_64
2、软件包名称构成
主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构
如下:
abrt-python.x86_64 2.1.11-60.el7.centos @os
- “.x86_64” 后缀表示64位系统的安装包,“.i686” 后缀表示32位系统安装包,安装包要和系统匹
- “el7” 表示主机平台,也就是操作系统发行版的版本,其中 “el7” 表示的是 centos7/redhat7,“el6” 表示centos6或者redhat6
- 最后一列中@OS表示的是 “软件源” 的名称, 类似于 “小米应用商店”, “华为应用商店”
3、安装软件
我们可以通过如下命令来安装软件包 (其中 -y 代表不询问直接安装)
格式:yum install (-y) 软件名
(1)安装 sl 小火车
sudo yum install -y sl
安装完成后输入sl
牛刀小试:按Ctrl+z停止
(2)安装lrzsz 工具
lrzsz 工具用于 windows 机器和远端的 Linux 机器通过 XShell 传输文件,安装完毕之后我们可以通过拖拽或者命令的方式将文件上传过去。
sudo yum install -y lrzrs
lrzrs在我们官方软件的列表中,但是官方软件的列表只包含了一部分经过测试的运行稳定可靠的软件。有一些软件并没有被纳入 Centos、Ubuntu、Kail等相关生态平台的官方软件集合中,如果我们想使用这些软件,需要安装 非官方软件集合列表:epel-realse
sudo yum install -y epel-realse
安装完成输入 rz 或者直接将电脑文件拖入目录即可上传文件
于是上传文件就非常方便了
注意事项
- 安装软件时由于需要向系统目录中写入内容,一般需要 sudo 或者切到 root 账户下才能完成
- yum安装软件只能一个装完了再装另一个;正在yum安装一个软件的过程中,如果再尝试用yum安装另外一个软件,yum会报错
- 软件和软件之间是有关联的,即具有一定的耦合度; yum 为了解决软件之间相互依赖的问题,有时候在安装一个软件会连带安装其他一些软件
4、卸载软件
yum remove 软件名
我们卸载掉之前安装的sl小火车
Ⅱ.vim编辑器
一、认识vim
1、vim概念
- vi/vim的区别简单点来说,它们都是多模式编辑器,不同的是vim是vi的升级版本,它不仅兼容vi的所有指令,而且 还有一些新的特性在里面。例如语法加亮,可视化操作不仅可以在终端运行,也可以运行于x window、 mac os、 windows
- vim是Linux 系统上一款强大的文本编辑器,类似于我们windows里的记事本。由于使用它便捷,高效的特点使它成为了目前最强大的编辑器,但是它最大的缺点之一就是使用门槛较高。
2、模式及其切换
vim编辑器有12种模式,但是我们主要使用的就三种,掌握这三种就可以使用vim了。
(1)命令行模式
控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode。vim一打开以后,默认的模式就是命令行模式。
(2)插入模式
只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。该模式是我们后面用的最频繁的编辑模式。在命令行模式下,按键盘上的i建,或者a和o都可以进入插入模式。
(3)底行模式
文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。 在命令模式下,shift+: 即可进入该模式。要查看你的所有模式:打开vim,底行模式直接输入:help vim-modes。
以上就是三种模式的主要功能,无论在任何模式下,只有无脑按ESc就可以进入命令行模式,然后再从命令行模式进入插入模式或者底行模式。
此时借用一位大佬的图:
二、vim使用
1、vim的指令(重要)
下列是总结的一些较常用指令
命令模式
打开vim时默认的就是命令模式,如果处于其他模式,只需要按ESc就可以回到命令模式。
光标移动:
命令 | 功能 |
---|---|
i | 进入插入模式,从光标当前位置输入字符 |
a | 进入插入模式,从光标当前位置的下一个位置输入字符 |
o | 进入插入模式,插入新的一行开始输入字符 |
ESc | 从其他模式进入命令模式 |
h,j,k,l | 对应光标的左下上右 |
G | 光标移动到文本的末尾 |
nG | 比如6G,光标跳转到第6行 |
gg | 光标移动到文本的开始 |
^ | 光标移动到当前行的行首 |
$ | 光标移动到当前行的末尾 |
删除文字:
命令 | 功能 |
---|---|
x | 小写x,每按一次,删除光标所在位置的一个字符 |
nx | 比如6x,删除从光标开始的6个字符 |
X | 大写X,每按一次,删除光标所在位置的前一个字符 |
nX | 比如6X,删除光标所在位置之前的6个字符 |
dd | 删除光标所在的当前行 |
ndd | 比如6dd,删除光标所在行开始的下面6行 |
复制剪切:
命令 | 功能 |
---|---|
yy | 复制光标所在行 |
nyy | 比如6yy,复制包括当前行向下数的6行 |
p | 粘贴yy复制的内容 |
np | 比如6pp,将复制内容粘贴6次 |
yw | 复制光标所在位置到行尾的字符 |
nyw | 比如6yw,复制光标所在位置开始的6个字符 |
替换:
命令 | 功能 |
---|---|
r | 替换光标所在处的字符 |
R | 替换光标所在位置的字符,直到行尾 |
撤销:
命令 | 功能 |
---|---|
u | 撤销上次执行的操作,多按几次可以撤销多个操作 |
ctrl+r | 恢复撤销 |
更改:
命令 | 功能 |
---|---|
cw | 更改光标所在位置到行尾的字符 |
cnw | 比如c6w,更改光标所在位置开始的6个字 |
插入模式
在命令模式下,按i,a,o都可以计入插入模式。
插入模式就和我们在Windows中的记事本一样,之间输入字符就可以。
底行模式
在命令模式下,按:也就是(shift + 封号)进入底行模式。
命令 | 功能 |
---|---|
set nu | 在文本中的每一行之前显式行号 |
set nonu | 去掉文本中的行号 |
vs 文件名 | 分屏,同时打开多个文件编辑,按ctrl+ww转换光标所在文件 |
wq | 保存内容,并且退出vim编辑器 |
q | 退出vim编辑器 |
w | 保存内容 |
q! | 强制退出vim编辑器 |
w! | 强制保存内容 |
/+字符 | 在文本中搜索字符 |
以上就是vim的基本操作,虽然很多,也比较难记,只要使用的多了就熟练了。
2、vim配置
我们使用vim编辑器主要就是为了写代码,在Windows下的VS2019中,在使用库函头文件等内容时,会出现代码提示,而且输完一行语句以后,按回车会自动缩进,并且还有代码高亮等等,使我们写代码更加发便高效,以及美观。
但是此时Linux上的vim编辑器就没有上面的功能,在上面写代码就像在记事本上写代码一样。
但是vim编辑器是可以配置的,可以配置成和vs2019一样,有代码高亮,提示,缩进等内容。
话不多说直接上链接:
VimForCpp: 快速将vim打造成c++ IDE (gitee.com)
vim详细操作:
GitHub - wsdjeg/vim-galore-zh_cn: Vim 从入门到精通
Ⅲ.gcc/g++编译器
1.程序的编译和运行
一个源文件(.c)变成可执行程序(.exe)需要经历四个步骤,预处理,编译,汇编,链接
使用gcc编译器来编译写的code.c源文件,然后会在当前目录下生成一个可执行程序,再运行这个可执行程序就会显示出程序的执行结果。
- 用法:gcc 选项 源文件 -o 目标文件名
- 功能:将源文件编程成可执行程序
- 常用选项:
-E:从当前文件开始,进行完预处理停止,生成的文件我们一般加后缀.i。
-S:从当前文件开始,进行完编译停止,生成的文件我们一般加后缀.s。
-c:从当前文件开始,进行完汇编停止,生成的文件我们一般加后缀.o。
2.使用gcc工具完成操作
格式:gcc+[选项]+要编译的文件+[选项]+[目标文件]
(1)预处理
预处理的作用:
- 将头文件展开,复制到源文件中
- 去掉注释
- 进行宏替换
- 处理条件编译
格式:gcc+-E+文件+-o+[目标文件]
实例:
gcc -E test.c -o test.i
- “-E”是让 gcc 在预处理结束后就停止,注意必须是大写。
- “-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。
(2)编译(生成汇编)
编译器的作用:将预处理生成的.i文件中的内容都转换成汇编语言。
在编译阶段,gcc 首先要检查代码的规范性、语法的正确性等,以确定代码的实际要做的工作,在检查无误后,gcc 会把代码翻译成汇编语言。
格式:gcc+-S+文件+-o+[目标文件]
实例:
gcc -S test.i -o test.s
- “-S”表示整个过程截止到编译结束,注意必须是大写
(3)汇编(生成机器码)
汇编的作用:将编译生成的.s文件中的内容都转换成二进制机器码,因为计算机只能读懂机器码。
在汇编阶段,gcc把编译阶段生成的“.s”文件转成目标文件,此时的文件都由01组成,是计算机可以看懂的二进制文件。
格式:gcc+-c+文件+-o+[目标文件]
实例:
gcc -c test.s -o test.o
- “-c”表示整个过程截止到编译结束
(4)连接(生成可执行文件或库文件)
在成功编译之后,就进入了链接阶段,连接起不同的.o文件最终形成可执行程序。
格式:gcc+文件+-o+[目标文件]
实例:
gcc test.o -o test
3.函数库
系统函数库
在我们的C程序中,并没有定义 printf 的函数实现,那我们是怎样使用 printf 函数的呢?
系统把这些系统自带的函数的定义都放到了 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是相当于链接到 libc.so.6 库函数中去,这样就能找到函数 printf 的定义了
动态链接和静态链接
动态链接和静态链接是指在编译和链接程序时,将程序所需的库文件链接到程序中的不同方式。
静态链接:
是将程序所需的库文件在编译时链接到程序中,生成一个独立的可执行文件。这样生成的可执行文件比较大,但是运行时不需要依赖外部库文件,因此具有较好的可移植性和稳定性。
动态链接:
是将程序所需的库文件在运行时动态加载到内存中,程序只需要链接到库文件的接口,而不需要将整个库文件复制到程序中。这样生成的可执行文件比较小,但是运行时需要依赖外部库文件,因此具有较好的灵活性和可维护性。
总的来说,静态链接适用于需要独立运行的程序,而动态链接适用于需要共享库文件的程序。
Linux上(Windows上也如此)gcc默认生成的可执行程序,是动态链接的(dynamically Linked)。
如果我们就想让test.c静态链接形成可执行程序可通过下面的语句实现:
格式:gcc 源文件 -o 可执行程序名 -static
- 一般系统会自动携带C语言动态库,C语言静态库可能没有安装,如果没有的话就需要自己安装,安装输入
sudo yum install glibc-static
- 编写一个test.c程序输入
gcc test.c -o test_s -static
- 用file指令发现test_s是静态链接的(statically linked)
可见,静态链接形成的可执行程序存储空间是动态链接的10多倍
Ⅳ.项目自动化构建工具Make/Makefile
1.Make/Makefile的介绍
- makefifile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编 译,极大的提高了软件开发的效率。
- make是一个命令工具,是一个解释makefifile中指令的命令工具,一般来说,大多数的IDE都有这个命 令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefifile都成为了一 种在工程方面的编译方法。
- make是一条命令,makefifile是一个文件,两个搭配使用,完成项目自动化构建。
2.Make/Makefile的简单使用
(1)Make/Makefile的初始化
首先,我们需要创建一个Makefile文件,命名为Makefile。Makefile的基本格式如下:
target: dependencies command
其中,target表示目标文件,dependencies表示依赖文件,command表示执行的命令(依赖方法)。
对于我们的例子,我们可以创建一个Makefile文件,内容如下:
main: main.c gcc -o main main.c
这个Makefile文件表示,我们的目标文件是main,依赖文件是main.c,执行的命令是gcc -o main main.c
接下来,我们在终端中进入程序所在的目录,执行make命令:
make
这时候,Make会自动读取Makefile文件,根据文件中的规则进行编译和构建。如果一切顺利,我们就可以在当前目录下看到一个名为main的可执行文件。
如果我们修改了main.c文件,需要重新编译程序,只需要再次执行make命令即可。
举个栗子:我们写一个测试,用main.c ,pp.h, pp.cpp三个文件实现
编写 makefile,最重要的是理解依赖关系和依赖方法:
- 依赖关系—— 目标文件:依赖文件
- 依赖方法—— 源文件形成目标文件需要执行的指令
- 被.PHONY修饰的对象就是一个伪目标
(伪目标 不依赖任何文件,依赖方法是 rm -f 指令;其中 .PHONY 修饰 clean 表示其是一个伪目标,伪目标总是被执行)
建立一个Makefile文件,注意文件名必须是makefile或Makefile,不能是其他名称,否则make不能识别。
注意:
依赖方法是 gcc 编译,依赖方法的执行指令必须以 [Tab] 键开头,特别注意不能是四个空格
例:[TAB]+g++ pp.cpp -o pp.o
(2)Make/Makefile的使用
接下来,我们在终端中进入程序所在的目录,执行make命令:
删除make指令生成的文件则用刚刚定义的clean
make clean
伪目标总是被执行 的意思就是不管你有没有文件或修改,都会执行定义的clean指令
相对应的就是make指令:只有没有文件或文件被修改才能使用
补充:
可通过 格式:stat+文件名 查看文件的属性信息
- Access 指最后一次读取的时间(访问)(比如在终端上用cat、more 、less、grep、 cp 、file 一个文件时都应该更新这个时间,不过它不会每次都更新,因为访问是个非常频繁的操作,每一次我们有意无意的操作,系统都更新它的时间是没必要的)
- Modify 指最后一次修改数据的时间(修改)(意思为更改,更改的是内容,“或者“写入)
- Change 指最后一次修改元数据的时间(改变)(意思为改变,改变的是状态或属性,比如对一个文件或者目录作mv、chown、chgrp操作)
Ⅴ.gdb调试代码
1.什么是gdb
GDB (GNU Debugger)是一个强大的命令行工具,可以帮助开发人员调试用各种编程语言(包括 C、 C + + 和汇编)编写的程序。它适用于大多数基于 Unix 的系统,包括 Linux 和 macOS。
2.debug和release
(1)Debug称为调试版本,它在源代码的基础上不作任何优化,便于程序员调试程序。
(2)Release称为发布版本,它往往是对程序进行了各种优化,例如减小程序大小和加快运行速度等,以便用户很好地使用。
(3)这两种状态下的代码运行结果可能会不同。
只有debug版本的程序才能调试,gcc默认生成的程序是release版本的,如果想生成debug版本的可执行程序可以在编译语句后面加上-g
若用release版本调试则
需要输入:
g++ fib.cpp -o fib -g
生成debug版本才能使用
3.gdb调试操作
以调试fib为例,简单说明最基本的几个命令,下面是gdb的操作方法。源码如下:
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
int f[100];
int n;
void print(int n)
{
for(int i=1;i<=n;i++)
cout<<f[i]<<" ";
}
int main()
{
cout<<"hello"<<endl;
cout<<"I"<<endl;
cout<<"am"<<endl;
cout<<"linux"<<endl;
f[1]=1;
f[2]=1;
cin>>n;
for(int i=3;i<=35;i++)
{
f[i]=f[i-1]+f[i-2];
}
print(n);
cout<<n<<endl;
return 0;
}
(1)进入调试
格式:gdb 可执行程序文件
输入:gdb fib 进入调试,进入gdb就可以输入指令了
(2)显示源代码
格式:list/l 数字
list 默认展开源代码的前十行,如果还想看到后面的内容可以点击Enter十行十行展开,加入数字表示从第几行显示
(3)断点的添加、删除和信息显示
指令 | 全称 | 功能 |
---|---|---|
b | breakpoints | 打一个断点 |
info b | info break | 查看当前断点 |
d | delete breakpoints (n) | 删除断点 |
格式:break+代码行数/b+代码行数 || break+代码行数+if+条件/b+代码行数+if+条件
格式:info break/info b
格式:delete+断点编号/del+断点编号
如上图的演示,打断点的时候,b后面加行号,删除断点的时候d后加断点的序号
(4)run运行调试程序与continue继续运行
指令 | 全称 | 功能 |
---|---|---|
r | run | 调试运行 |
n | next | 逐过程调试 |
s | step | 逐语句调试 |
c | continue | 运行到下一个断点处停止 |
格式:run/r r 开始运行到断点
格式:continue/c c 继续运行至断点或者程序结束
格式:next/n next为gdb的逐语句调试,当遇到函数调用时,不进入函数体,相当于VS的F10
格式:step/s step为gdb的逐过程调试,当遇到函数调用时,进入函数体,相当于VS的F11
(6)查看某个变量的值
指令 | 全称 | 功能 |
---|---|---|
p | 临时查看变量值 | |
display | 常显示变量 | |
undisplay | 取消变量常显示 |
格式:print var(var表示任何一个变量或表达式)
在调试过程中,我们需要查看当前某个变量值的时候,可使用 print 命令显示该值,但是只能显示一次下次不会再显示。
格式:display var(var表示任何一个变量或表达式)
使用 display 命令就可以一直显示该值。
undisplay只能删除所有显示值
(7)退出gdb
VS中退出调试可以输入Shift+F5
格式:quit/q
4.其他命令
指令 | 全称 | 功能 |
---|---|---|
bt | breaktrace | 查看函数堆栈 |
finish | 执行完当前函数 | |
until+n | 跳转到指定行 |
- until:当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体
- until+行号: 运行至某行,不仅仅用来跳出循环
- finish: 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息
- call 函数(参数):调用程序中可见的函数,并传递“参数”,如:call gdb_test(55)
- disable 断点号n:暂停第n个断点
- enable 断点号n:开启第n个断点
- clear 行号n:清除第n行的断点