目录
一,vim(Linux常用文本编辑器)
1.1 关于vim
我们之前是在VS2022编写的代码,VS2022称为IDE,也叫做集成开发环境,集合了C/C++等多种语言的预处理,编译,调试和链接等多种功能。而在Linux下我们编写代码主要是通过vim+gcc/g++来编写代码的。所以vim简单来说就是类似于Windows的记事本,是Linux下的文本编辑器。它的总体功能非常单纯,就是读取文件内容,并可以对文件内容进行修改。
问题:为什么要用vim来编写代码?
解答:Linux操作系统是一个总称,Linux下也有很多版本,而且几乎所有的Linux操作系统都自带vim,并且我们前期使用vim来编写代码,可以让我们在学习阶段熟悉命令行操作
1.2 vim的三种常用模式
vim是一款多模式的编辑器,其中包括 “命令模式”,“插入模式”,“底行模式”
命令模式
命令模式(Normal mod)是vim刚打开时的模式,在该模式下,我们可以控制屏幕光标的移动,进行字符的单个或行的删除,复制剪切粘贴等操作
插入模式
在插入模式(Insert line mode)下,我们可以控制光标的移动,并且在光标的左边进行字符的插入删除等,而且只有在这个模式下我们才能从键盘上进行字符输入,是我们后面编写代码时最常用的编辑模式
底行模式
底行模式(Command mode)下,我们可以对我们当前屏幕上的内容进行保存退出,也可以进行查找字符串等操作。
1.3 各种模式的切换(一图览)
1.4 vim命令模式各命令集合
【移动光标】
①k:光标上移
②l:光标右移
③j:光标下移
④h:光标左移
⑤$:将光标搞到所在行末尾
⑥^:将光标搞到所在行开头
⑦gg:将光标移动到总文本开头
⑧Shift+g:将光标搞到总文本末尾
⑨数字+Shift+g:将光标搞到指定行末尾
⑩数字+Enter:将光标向下移动指定行
【删除】
①x:删除光标所在位置字符
②nx:删除光标所在位置后面的n个字符
③X:删除光标前面的一个字符
④nX:删除光标前面的n个字符
⑤dd:删除光标所在行的所有字符
⑥ndd:删除光标所在行开始往下的n行所有字符
【复制粘贴】
①yy:复制光标所在行的内容到缓冲区
②nyy:复制光标所在行开始往下的n行到缓冲区
③yw:将光标所在位置到该行末尾的字符复制到缓冲区
④nyw:将光标所在位置往后的n个字符复制到缓冲区
⑤p:将已复制的内容在光标的下一行粘贴上
⑥np:粘贴n次
【剪切粘贴】
①dd:剪切光标所在行
②ndd:剪切光标所在行开始往下的n行
③粘贴命令和上面一样
【撤销上步操作】
①u:撤销上步操作
②Ctrl+r:恢复上次撤销
【替换】
①r:替换光标所在位置的单个字符
②R:替换光标所在位置的字符,知道Esc才停下(其实就是进入了替换模式,这个模式用得不多)
【更改】
①cw:将光标所在位置开始到该行末尾得字符删除,并进入插入模式
②cnw:将光标所在卫视开始往后得n个字符删除,并进入插入模式
【翻页】
①Ctrl+b:上翻一页
②Ctrl+f:下翻一页
③Ctrl+u:上翻半页
④Ctrl+d:下翻半页
1.5 vim底行模式各命令集合
在使用底行模式之前,先按ESC键确定已经处于命令模式,然后再Shift+; 进入底行模式
【行号设置】
①set nu:显示行号
②set nonu:取消行号
【保存退出】
上面一图览已经介绍过,如果有意外情况无法退出,在wq得后面加上一个 ‘!’ 表示强制退出
【执行指令】
!+指令:可以在不退出vim得前提下执行Linux的指令,比如查看目录,编译当前代码等
1.6 vim配置
在目录/etc/下面有个名为vimrc的文件,这是系统中公共的配置文件,对所有用户有效;在每个用户的工作目录下(cd ~),可以自己建立私有的配置文件,命名为" .vimrc ",这是该用户的配置文件,仅对该用户有效
例如,我们普通用户在自己的主目录下建立了" .vimrc "之后,在文件中输入set nu保存退出后,下一次打开vim时就会自动显示行号
vim的配置比较复杂,所以这里给一个命令,自动完成vim的配置,使其自动补全,错误提示,行号显示等功能全有了,命令如下;
curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh
然后等待安装配置
也可以删除配置,命令如下:
bash ~/.VimForCpp/uninstall.sh
二,gcc/g++(Linux环境下C/C++编译器)
2.1 关于gcc/g++
我们最常用的VS2022或者VS2019我们习惯性把它称为编译器,这其实并不准确,VS系列我们称为“集成开发环境”,简称“IDE”,集合了C/C++等多种语言的预处理,编译,调试和链接等多种功能
gcc和g++才是最正宗的C/C++代码编译器,他在执行编译时一般有下面四个步骤:
①预处理:头文件展开,宏替换,去注释,条件编译等
②编译:将C/C++代码转化成汇编语言
③汇编:将编译后的汇编代码转化为二进制机器语言
④链接:将汇编后产生的二进制语言进行链接
(关于这四个步骤,已经在文章“C语言代码是如何编程二进制代码的”里详细介绍过,这里不再赘述)
2.2 gcc/g++使用及其选项
语法:gcc/g++ 选项 文件
功能:根据用户的需求,对C/C++代码进行各种操作
常用选项:
① -E 只进行预处理,不生产文件,所以需要用重定向 ‘ > ’ 输出到一个文件里,不然就会把预处理结果打印再屏幕上
② -S 将代码编译成汇编后停止,不生产可执行文件,也不进行链接
③ -c 编译到目标代码
④ -o 将处理结果输出到指定文件,并且-o 后面要紧跟着文件名
⑤ -static 此选项将对身生成的可执行文件采用静态链接,因为默认是动态链接(后面讲)
⑥ -g 生成调试信息,如果不加则默认生成release版本
⑦ -shared 此选项将尽量使用动态链接,生成的文件较小
⑧ -w 不显示任何警告信息
⑨ Wall 显示所有警告信息
⑩ -O0/-O1/-O2/-O3 编译器优化选项的四个级别,-O0表示无任何优化,-O3表示优化级别最高
//test.c
#include<stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
2.3 动静态库
静态库是指编译链接最后生成可执行文件时,把库文件的代码全部加载到可执行文件中,这样可以在运行时不再需要额外的库文件了,而且也可以让代码执行的速度更快,但是生成的可执行文件比较大。静态库一般以.a为后缀
动态库是指在编译链接生成可执行代码时没有将库文件加载到可执行文件中,而是在运行时由链接文件加载库,这样可以使生成的可执行文件大小比较小,但是会让运行的时间变长。动态库一般以.so结尾
2.4 动静态链接
动态链接:
优点:节省空间,文件体积小,加载速度块
却带你:依赖动态库,可移植性比较差
静态链接:
优点:不依赖链接库,可移植性很高
缺点:生成的可执行文件巨大,浪费空间
gcc和g++默认使用动态链接生成可执行文件:
我们也可以使用ldd命令查看动态链接所依赖的库:
前面我们将gcc/g++的选项时讲过,使用-static选项可以采用静态链接
三,MakeFile(Linux自动化构建项目工具)
3.1 关于MakeFile
①会不会写MakeFile,从侧面说明了一个人是否具备按此大型工程的能力
②一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的 规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
③makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编 译,极大的提高了软件开发效率
④make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命 令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法
⑤make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。
3.2 依赖关系和依赖方法
依赖关系:文件①的改变能影响到文件②,那么就称文件②依赖于文件①
举个例子:test.c经过gcc编译后能形成test可执行文件,如果改变test.c回影响test执行的结果,那么就说明test依赖于test.c
依赖方法:如果说文件②依赖于文件①,那么通过文件①得到文件②的方法就是文件②依赖与①的依赖方法
举个例子:如果说test可执行文件通过test.c经过 gcc test.c -o test 编译后得到的,那么这个 gcc test.c -o test 就称作test依赖于test.c的依赖方法
3.3 多文件编译
gcc/g++是支持多源文件同时同时编译的:
但是以后使用gcc编译多个源文件时,一般不适用.c文件直接编译,一般都是先生成.o的二进制文件,然后通过链接生成可执行文件,如下图:
问题:为什么要这样搞?
解答:为了使项目中的源文件解耦
①如果是源文件直接编译,那么如果对一个源文件做修改,再生成可执行文件的时候就要将所有的源文件全部重新编译
②如果用链接的方式生成,那么改变一个源文件时,就只需要重新对这个源文件单独做重新编译即可,不影响其他的源文件
在有很多个源文件的情况下,我们再用gcc一个一个去编译的话,太复杂,所以需要用到我们的make和MakeFile了
3.4 MakeFile文件与make命令
先创建makefile:
然后编写MakeFile:
MakeFile最简单的编写格式就是,先写出文件的依赖关系,然后写出这些文件之间的依赖方法即可,如下图:
然后直接在命令行输入 “ make ” 命令就可以自动执行gcc编译生成可执行文件
3.5 make clean项目清理
在我们每次重新生成可执行程序前,都应该将上一次生成的可执行程序进行删除清理,而同样的,如果我们每次都去rm清理的话,巨麻烦,所以我们也可以用make clean命令来清理
改写makefile文件:
3.6 make原理
①make命令会在当前目录下找名字叫“Makefile”或“makefile”的文件。
②如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“test”这个文件, 把这个文件作为最终的目标文件。
③如果test文件不存在,或是hello所依赖的后面的hello.c文件的文件修改时间要比hello这个文件新,那么,他就会执行后面所定义的依赖关系来重新生成hello这个文件。
④make会一层层去找文件的依赖关系,知道最终编译出第一个目标文件
⑤在寻找的过程中,如果出现错误,例如最后被依赖的文件找不到,那么make就会直接退出并报错
四,gdb(Linux下代码调试器)
4.1 关于调试
程序发布方式分为:
①release:不可调试,不会生成的可执行程序不会添加任何调试信息,一般用于项目的发布版
②debug:与release相反,会在可执行程序里添加调试信息方便调试,一般用户项目开发阶段
在Linux当中gcc/g++默认生成的可执行程序是release版本的,不可被调试,所以需要添加 -g 选项生成debug版本
4.2 关于gdb
与我们以前在VS系列系列窗口化调试不同,gdb调试器是一种“伪命令行”式的调试器,如下图片:
进入gdb后,我们需要和对Linux发送命令请求一样,对gdb发送各种指令来进行调试,并且只有debug版本的可执行程序才能进入调试,release不能
4.3 gdb命令集合
进入gbd模式后,不能立马调试,要先输入start开始调试才能输入各种指令选项
【调试】
① run/r:运行代码,直接显示运行结果
② next/n:逐过程调试
③ step/s:逐语句调试
④ until 行号:运行跳转到指定行
⑤ finish:执行完当前正在调用的函数后停下来,main函数除外
⑥ continue/c:运行到下一个断点处
⑦ set var 变量名=n:修改指定变量值为x
【显示】
① list/l n:显示从第n行开始的源代码
② list/l 函数名:显示指定函数名的源代码
③ print/p 变量:打印变量的值
④ print/p &变量:打印变量的地址
⑤ print/p 表达式:打印表达式的值,通过表达式可以修改变量的值
⑥ display 变量:将变量加入常显示并对变量打上编号,就是每次停下里都显示它的值,类似VS系列的监视窗口
⑦ display &变量:常显示变量的地址
⑧ undisplay 编号:取消指定编号变量的常显示
⑨ bt:查看各级函数调用及参数
⑩ info/i locals:查看当前栈帧中局部局部变量的值
【断点】
① break/b n:在第n行设置断点,并对其打上编号
② break/b 函数名:在某函数体内第一行设置断点
③ info breakpoint/b :查看已打的断点信息
④ delete/d 编号:删除指定编号的断点
⑤ disable 编号:禁用指定编号的断点
⑥ enable 编号:重新启用断点
【退出】
quit/q:退出gdb,会询问是否退出
五,yum(Linux下的软件包管理器)
5.1 关于yum
Linux系统安装软件的方法大致有下面三种:
①下载程序的源代码,手动进行编译,得到可执行程序
②获取rpm安装包,通过rpm命令进行安装,但是此方法未解决软件的依赖关系
③通过yum进行安装软件
yum是一个在Fedora,RedHat以及CentOS中的软件包管理器,能够从指定的远端服务器自动下载rpm包并进行安装,自动处理依赖关系,极大化渐变了传统繁琐,复杂的安装方法。软件包和软件包管理器,就好比 “app应用” 和 “应用商店” 的关系
一个服务器同一时刻只能允许一个yum进行安装,这和手机上只能同时安装一款软件是一样的,并且yum在下载的过程重必须保持网络通畅,使用下面命令可以判断网络是否通常:
ping www.baidu.com
5.2 查找软件包
yum list
该命令会罗列出yum的全部的可供下载的软件,按字母排序,但是显示的列表一共有2万四千多行,所以我们查找软件包一般用grep命令筛选指定名称的包,下面我们以查找lrzsz为例,该软件可以使用rz和sz命令实现Linux于Windows之间的文件和信息互传:
yum list | grep lrzsz
①lrzsz是软件名称,后面的x86_64后缀表示需要64位的系统才能安装
②中间的表示:主版本号(0).次版本号(12).源程序发行号(20)-软件包的发行号.cpu架构
③“ el7 ” 表示操作系统发行版的版本,表示 “centos3/redhat7 ”
④最后的@os表示“软件源”的名称,类似于“x小米应用商店”,“华为应用商店”这样的概念
5.3 下载并安装
我们直接下载lrzsz软件包,执行如下命令:
sudo yum install lrzsz
yum会自动找到都有哪些软件包需要下载,根据系统提示操作,最后出现complete时安装完成
yum安装软件时只能进行一个,如果一个yum在下载时运行另一个yum,另一个yum会报错
5.4 Linux与本地Windows文件互传
这时候我们前面下载的lrzsz就派上用场了
语法:rz -E
功能:从本地Windows上传文件到Linux云服务器
下面是从Linux上拉取软件到本地Windows
语法:sz 文件名
功能: 将Linux云服务器文件拉取到本地Windows
5.5 卸载软件
sudo yum remove 软件名
执行该指令后,yum会自动卸载该软件并移除所有有关的依赖关系,出现complate时,完成卸载
注:yum是Centos环境的软件包管理工具,Ubuntu环境下叫做“apt”,两者在使用上是一样的,只是名称区别