首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Linux操作系统-基础开发工具(一)

Linux操作系统-基础开发工具(一)

作者头像
海棠蚀omo
发布2026-01-12 16:38:45
发布2026-01-12 16:38:45
1170
举报

一.编辑器Vim

1.1Vim的基本概念

Vim 是 Linux 中一个高效、高度可定制的模态文本编辑器,是经典 vi 的增强版。它不仅兼容vi的有指令,⽽且还有⼀些新的特性在⾥⾯。例如语法加亮,可视化操作不仅可以在终端运⾏,也可以运⾏于x window、 mac os、 windows。

1.2Vim的多模式

常用的Vim模式有:命令模式,插入模式以及底行模式,这篇还会讲两种模式:视图模式,替换模式。

这些模式我们用下面的实例来更好的去理解:

此时我们创建一个test.c的文件,通过vim指令进入其中,首先展示的页面就默认是命令模式,我们此时如果想往上面写东西是不行的,要写东西就要进入插入模式,而命令模式进入插入模式要按下字母i:

此时我们通过按下字母i就进入到了插入模式,可以看到最下面有大写的INSERT,就说明此时处于插入模式。插入模式就相当于我们平常写代码的场景,上面我就在插入模式下写了一个简单的C语言程序。

而我们要想重新进入命令模式该如何做呢? 按键盘左上角的ESC即可退出插入模式,从而进入命令模式。

此时我要是想退出Vim的编辑模式,回到命令行模式该如何做呢? 此时就要进入到底行模式来完成相关操作,从命令模式进入到底行模式要按下shift+:,即可进入底层模式

此时我们按下之后就在最下面会后有”:“出现,我们输入wq即可保存并退出,wq是底行模式常用的指令,w是保存,q是退出。

并且由底行模式转换到命令模式同样也是按下ESC即可。

我们通过cat指令就能看到这个文件中我们写入的内容了。

那么有人可能会问:那我要是想从插入模式转换到底行模式,或者从底行模式转换到插入模式该怎么办呢?

答案是转换不了的,只能通过转换为命令模式再转成其他模式,命令模式作为中介。

经过上面的介绍,我们可以通过图来展示他们三者之间的关系:

1.3命令模式

下面我们来讲在命令模式下的一些常用指令。

1.3.1光标移动的相关命令

1.3.1.1.shift + g = G

这个命令的作用是直接将光标移动到文本末端的位置:

绿色的就是光标的位置,按下上面的命令之后可以看到光标就到了文本末端的位置。

并且n + shift + g能够直接跳到你想到的那一行,n就代表行数:

上面我就是按下了5 + shift + g,光标就跳到了第五行的位置。

1.3.1.2.gg

这个命令的作用就是和上面的相反,它会直接让光标移到文本开始的位置,shift+g的最上面两幅图反过来就是gg命令的作用,这里就不演示了。

1.3.1.3shift + $/shift + ^

这两个命令中shift + $的作用是定位到当前行的结尾,shift + ^的作用是定位到当前行的开始位置:

第一幅图是在中间的位置,后面两幅图就是按下上面的命令后光标会出现的位置。

1.3.1.4 h/j/k/l

这四个命令就是使光标能够上下左右移动,h是向左,j是向下,k是向上,l是向右,这四个指令的功能和键盘右下角的上下左右键是一样的,也就是你可以用这四个字母来进行移动光标,也可以用上下左右键来移动光标。

那么此时可能有人会问:那既然键盘上的上下左右键已经能完成上面的操作,为什么还要发明这四个字母呢?

原因就如上面所示,上面的键盘是上个世纪的键盘,我们可以看到那时的键盘上并没有上下左右键,所以为了实现上下左右的操作才发明了这四个命令。

1.3.1.5 w/b

这两个命令w的作用是以单词为单位,向右移动,b的作用是以单词为单位,向左移动。

这两个命令的应用场景就是当一行程序过长时,我们如果要移动到中间的某个位置,用h或l命令一次只能移动一格,效率太低,这时候就可以用w/b命令来进行移动。

上面就是光标起始位置和用w/b命令后光标的位置。

1.4.2编辑内容的相关命令

1.4.2.1 yy/p

这两个指令yy的作用就是复制,p的作用就是粘贴,这两个命令的作用想必大家很熟悉,和我们在windows系统下的ctrl + c,ctrl + v作用是一样的。

按下yy后,再按下p就会在当前行的下面复制粘贴上面的内容。

yy和p也是支持n + yy和n + p的操作,也就是复制n行以及粘贴n行:

上面的操作就是2 + yy和2 + p,也就是复制了2行,并将2行的内容粘贴了两次。

1.4.2.2 shift + ~

这个命令的作用就是实现大小写快速转换,如果此时的字母是小写,那么按下命令后就会变成大写,反之会变成小写:

上面的字母都是小写,那么按下相应的命令后就会变为大写,一次只能转换一个字母,上面我是一直按,将所有的字母变为了大写。

1.4.2.3 dd

这个命令的作用就是删除当前行:

上面就是执行了多次的dd命令,将6行删至2行。

并且n + dd的操作也是可以的,代表着一次删n行。

1.4.2.4 r + 字符

这个命令的作用就是替换光标所在位置的一个字符:

上面的光标此时停留在i字符的位置,我按下r + a之后就将i替换为a。

这个命令同样支持n + r + 字符的操作:

上面的操作就是6 + r + a,将printf替换为aaaaaa。

1.4.2.5 x/shift + x

这两个命令的x的作用是删除光标所在的字符,并且是向右删除,shift + x的作用是向左删除:

第一图就是起始状态,后面两幅就是多次调用x和shift + x后的效果。

1.4.2.6 u/ctrl + r

这两个命令u是撤销操作,ctrl + r是撤销u的撤销操作,撤销的操作想必大家都清楚,和我们在日常写代码时的ctrl + z的效果是一样的。

而ctrl + r是撤销u的撤销操作,也就是将代码还原成u撤销之前的样子。

1.5底行模式

下面我们来将底行模式下常用的一些命令

1.5.1 w!/q!/wq!

这仨个命令都是在其基础上加了一个!,作用就是强制,w!就是强制保存,q!就是强制退出,wq!就是强制保存并退出,我们来看示例:

上面我们将拥有者的w权限给去掉,此时当我们在转换成插入模式时,INSERT后面就会显示如第二幅图所示的警告,并且当我们切换到底行模式时,输入w,q或者wq都会报第三幅图所示的警告。

此时w!,q!和wq!的作用就体现出来了:

我们将头文件那一行复制粘贴了一遍,并用wq!强制保存并退出,此时我们再看文件中的内容,发现确实将粘贴的内容保存了下来。

1.5.2 :/key + n

这个命令的作用就是匹配搜索:

当我们输入:/printf并回车时,就会将相应的字符高亮出来,而n的作用就是按下n后光标就会跳到下个相应的字符的位置。

上面就是按了3次n后光标所在的位置。

1.5.3 ! + 指令

这个命令的作用就是在不退出vim的情况下执行指令,我们来看示例:

上面就是在不退出vim的前提下执行创建world.txt文件的操作,按下回车后就会显示第二幅图所示的提示,再次按下回车后就会返回vim的界面。

我们退出vim后通过ll指令就会看到world.txt文件确实创建成功了。

1.5.4 %s/dst/src/g

这个命令的作用就是将所有的dst字符替换为src字符:

上面就是通过这个命令将所有的printf替换为了cout。

1.5.5 set nu/set nonu

这两个命令set nu的作用是显示行号,set nonu隐藏行号:

上图就是经过set nu后程序就会显示行号,而执行set nonu命令过后就会回到第一幅图的状态。

讲到这里我们来看一种现象,当我们vim打开文件,但是并没有wq,而是直接将终端关闭了,会发生下面这种现象:

当我们重新启动终端后,再次通过vim打开文件,就会跳出上图的内容,我们主要看最下面的一行,有多种选项 ,我们这里选择R回复这个文件。

按下之后会跳出这个内容,我们再次按下回车后,就会回到正常的vim编辑模式下。

但是当我们正常wq退出vim后,再次通过vim打开文件就又会重新跳出上面的内容,这是为什么呢?

答案是因为它生成了一个.test.c.swp的隐藏文件,这个隐藏文件就会导致每次vim打开test.c的时候跳出上面的内容,解决方法就是直接把这个文件给删掉。

按理说下面该讲插入模式的相关命令了,但是没有必要,因为我们在日常写代码时所用到的各种命令就是插入模式的相关命令,这里就不过多赘述了。

1.6其他模式

1.6.1 视图模式

进入到视图模式需要按下ctrl + v,这个模式就需要讲的就是批量化注释和批量化去注释这两种操作。

1.6.1.1 批量化注释

批量化注释的操作分为:

1.ctrl + v 进入到视图模式

2.h/j/k/l 选择区域

3.shift + i 进入到插入模式

4.//

5.ESC

下面我来演示批量化注释的五个步骤:

这五幅图就是就是按照上面的五个步骤所产生的变化,值得一提的是视图模式可以直接通过shift + i转换为插入模式,但是反过来是不行的。

当然说是批量化注释操作,其实在第四步也可以更换为其他的操作,不是局限于加注释,主要是批量化的操作。

1.6.1.2 批量化去注释

批量化去注释的步骤为:

1.ctrl + v 进入到视图模式

2.h/j/k/l 选择区域

3.d 删除所选择区域的内容

下面演示这三步操作:

第三步的d操作就可以将选中的所有//给删除掉。

1.6.2 替换模式

要进入到替换模式需要按下shift + r,替换模式的作用就是可以直接在当前行写内容,替换原有的内容:

如上图所示,在没有进入插入模式的情况下,直接输入内容将原有的printf表达式给覆盖掉了,这就是替换模式的主要作用。

二.编译器gcc/g++

gcc和g++编译器相信大家都不陌生,我们在日常编写C语言或C++代码时就是用这两种编译器来使代码运行起来,下面我们利用Linux的环境来更加深入的理解gcc/g++编译器。

2.1 gcc vs g++

这两种编译器到底有什么区别呢?

gcc:C的编译器,只能用来编译C语言的代码

g++:C/C++的编译器,既可以用来编译C语言的代码,也可以用来编译C++的代码

2.1 gcc翻译C语言代码的过程

这里我们就要深入探讨gcc翻译C语言代码的具体过程,来更好地理解gcc编译器在Linux环境下的运行过程。

我们在使用gcc编译器来执行C语言的代码,会直接给我们生成一个可执行文件,会省略中间的过程,也就是一步到位。

而编译器gcc完整的翻译过程为:预处理,编译,汇编和链接,下面我们就针对这几个过程来详细介绍。

2.1.1预处理

预处理也会分为几个过程:头文件展开,去注释,宏替换和条件编译,我们用下面的示例来演示这四个过程:

第一幅图是我们写的程序,既然直接gcc编译C语言程序会一步到位,所以我们通过在其后面加上 -E 就可以使gcc的翻译过程在做完对源文件的预处理后停下来。

并且我们在给预处理生成的文件命名时后缀要为 .i,前面的名字可以随便起,但后缀要是 .i 。

完成上面的步骤后,我们vim进到文件中,拉到最下面main函数中我们可以很直接的看到上面四个过程中的宏替换和去注释这两步,所有的M都被替换成100,并且所有的注释都消失了。

那么剩下的两个过程呢?

我们先说头文件展开,我们可以通过行号观察到明明我们的程序只有短短十几行,但是生成的预处理文件却有800多行,上面那么多代码是什么呢?

答案是头文件中的内容,头文件展开顾名思义就是将头文件中的内容在当前文件中展开。

那最后的条件编译又是什么呢?

我们对上面的代码作出一些修改能更明显地看到:

上面我并没有定义宏VERSION,所以程序就会走else的代码,在code.i中我们也可以看到代码就只有else中行的代码。

下面我又加上了对VERSION的定义,此时我们再看code.i就会发现代码剩下的就是ifdef中的代码。

上面的过程其实就是条件编译,对于不符合的代码,经过条件编译后就不会进入到code.i文件中,也就是条件编译的本质就是对代码做裁减

2.1.2 编译/汇编

这两个我们放在一起讲,编译的过程就是把C语言的程序转化为汇编语言,汇编的过程就是将汇编语言翻译为二进制文件(可重定位目标二进制文件)。

和上面的预处理过程一样,编译和汇编也有相应的令其翻译过程停下的相关指令:

编译:

汇编:

文件的后缀和上面的预处理是一样的原因。

上面我们就通过相应的指令创建了在经过编译和汇编过程后所形成的文件,并通过vim进入其中看到如上图所示程序,上面的程序我们是不太能看懂的,尤其是二进制文件,一堆符号。

那么为什么这两个过程要放在一起讲呢?

我们可以思考一个问题:为什么gcc翻译C语言的代码要有编译和汇编的过程,也就是为什么要将C语言的代码转成汇编语言,再转成二进制文件?

要解决这个问题我们就要了解计算机语言的发展过程:

计算机语言的发展就是上面的三个阶段,机器语言就是二进制编程,高级语言就是我们现在使用的C/C++/JAVA等高级语言,计算机语言的发展过程其实就是为了成为更好的符合人类的自然语言,就像最初的二进制编程就是纸带编程,相当的不方便,而像现在我们所学的高级语言就方便了很多。

但是我们计算机的底层还是只能识别二进制的代码,也就是0和1组成的相关数据和指令,所以我们写成的代码要想让计算机认识,就要转变成二进制的代码,而不直接从高级语言直接转化成二进制编程的原因有很多,包括难度很高等,所以就形成了现在的转换过程,先转换为汇编语言,再转成二进制的代码。

2.1.3链接

那为什么会有链接的过程呢?上面通过汇编后不是已经把代码转化为二进制形式了吗?

我们来执行一下汇编后的文件:

我们给拥有者加上x的权限后,发现依旧无法执行,原因如上图所示是因为她本身并不是一个可执行的文件,那为什么它不可执行呢?

这是因为在这个文件中我们所用到的比如:printf,scanf等函数在这里面只有声明,没有实现。

大家可以思考一下我们在使用上面的相关函数时,你写的代码中有函数的实现吗?

答案是没有的,这些函数的实现是在C语言标准库中,而链接的作用就是将二进制文件和C语言标准库关联起来,使其能找到函数的实现,找到后再回来。

而链接的指令就是:

链接就不需要另外加指令了,因为经过链接后就会生成一个可执行文件,就和我们上面的一步到位是一样的效果。

这里生成的code文件就是我们要的可执行文件了。

上面我们讲了能够将代码和C语言标准库关联起来,那C语言标准库在哪儿呢?

通过第一行的指令我们就能找到C语言库的位置,而C语言标准库就是最后被绿色高亮的那个文件。

如何将两者关联起来就是编译器gcc的事了,gcc知道库和头文件在哪里,这中间的过程我们就不用操心了。

三.动静态库

3.1动静态库的分类

我们上面所说的库分为动态库和静态库这两类:

上图就是在Linux和windows环境下动态库和静态库文件的后缀,所以说我们上面所提到的C语言标准库文件后缀就是.so,也就是动态库。

并且以Linux为例,我们给库文件命名时一般采取:lib + name + .so/.a的命名方式,所以我们要看一个库的名字是什么,就要去掉lib和后缀。上面的C语言标准库名字其实就是c-2.17,2.17就是它的版本。

3.2动态链接

动静态库直接讲概念会比较晦涩难懂,下面我用一个简单的例子来说明: 先以动态库举例,比如你家里没有电脑,但是你想要玩电脑就要去网吧之类的地方对吧,到了网吧,开了一台你经常玩的机子,然后玩了几个小时之后你下机了,然后回家。

上面的例子中,没有电脑的情况就是我们的程序中没有实现只有声明,所以要去网吧,也就是去动态库里面找,而我们常玩的机子就是我们常用的函数的实现,我们去网吧的过程叫做库函数跳转,回家的过程叫做库函数返回。

这上面的整个过程也就是链接中的关联,也叫做动态链接。

而网吧的地址是编译器gcc给程序的,程序会按照gcc给的地址来找到网吧。

3.3静态链接

依旧以上面为例,突然有一天,网吧倒闭了,此时你就不能再去网吧玩了,但是你还是想玩,所以你哥去了这个网吧,把网吧库存的你那台机子给你买了回来,放在家里面,这样你以后既不需要再去网吧玩电脑了,在家就能玩。

上面的例子中,网吧就是静态库,把网吧的机子给你买回来放家里就是将静态库中的函数实现拷贝到你的程序中,这样程序就不会再去静态库中。

而静态链接就是上面的过程,静态链接我们需要那个函数的实现就会将静态库中的那个函数实现拷贝到程序中。

3.4动静态链接的优缺点

动态链接:

优点:节省内存空间

缺点:库函数跳转和返回会消耗一些时间,编译的完成依赖动态库,动态库有一旦出问题,程序就很大可能运行不起来。

静态链接

优点:不需要库函数跳转和返回,节省时间,一旦编译成功不依赖静态库,我将我需要的函数实现拷贝到我的程序中,之后你有什么问题就影响不了我。

缺点:可执行程序体积较大,占用的内存空间较大。

3.5动静态链接的注意事项

3.5.1

我们要弄清动态库和静态库的区别,在上面的例子中,动静态库虽然都是网吧,但是身份并不一样,在动态链接中,动态库确实是网吧,但在静态链接中,静态库就变成了二手电脑经销商,一定要弄清两者之间的区别。

3.5.2

在Linux中默认是使用动态链接的:

上面我们可以看到默认情况下是dynamically linked,也就是动态链接。

那我们要想让gcc执行静态链接呢?

我们就可以在正常的指令后面加上-static,这就要求gcc强制采用静态链接。

但是Linux环境下默认是没有安装C语言静态库的,我们要想实现上面的操作需要提前安装C语言静态库。

最后我们对比一下动态链接和静态链接生成的可执行文件就可以发现,动态链接生成的code文件大小为8481字节,而静态链接生成的code-static文件大小却是861336字节,相差100倍,我们就短短写了一二十行代码都相差这么多,所以Linux才默认用动态链接。

以上就是基础开发工具(一)的全部内容。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-11-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档