一、编辑器vim
1、概念
vim是一种常用于linux下的多模式编辑器。在vim中有好多模式,我们先了解这三种即可:分别是命令行模式(command mode)、插入模式(Insert mode)和底行模式(last line mode)。
1、正常/普通/命令模式(Normal mode)
控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode
2、插入模式(Insert mode)
只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。该模式是我们后面用的最频繁的编辑模式。
3、底行模式(last line mode)
文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。 在命令模式下,shift+: 即可进入该模式。
vim作为一种编辑器,它只能用来写代码,至于代码是否编译成功和是否能够运行成功,它一概不关注,它只能用来进行代码的编辑。
三种模式之间的切换:
注:q!(强转退出) ,wq(保存并退出)。
2、基本操作
1、进入vim
输入命令:vim 文件名。进入vim全屏幕编辑画面。进入之后是处于命令行模式,你要切换到插入模式才能够输入文字进行编辑。
2、模式切换
三种模式的切换见上图。
3、命令行模式
命令行模式下的常用命令:
1、yy:将光标当前所在行的内容进行复制。n yy:n表示具体整数,表示可以复制从该行开始的n行内容。
2、p:将复制的内容进行粘贴。n p:将复制的内容粘贴n行。
3、u:撤销操作。
4、ctrl + r:撤销u操作。
5、光标定位:
shift + g:将光标定位到文件的结尾。
gg:将光标定位到文件的开始。
n shift g :将光标定位到文件的任意一行。
shift + 6(^):将光标定位到当前行的最开始。
shift + 4($):将光标定位到当前行的结尾。
h、j、k、l:光标分别进行 左、下、上、右的操作。
6、dd:将光标所在行的内容删除。n dd:将光标所在行以及下面的n行内容删除。
dd + p:相当于剪切。
7、shift + ~:将字母进行大小写切换。
8、shift + r:进入替换模式。esc退出。
9、r:替换光标所在的字符。n r。
10、x or shift + x:删除光标所在的字符。n x。
4、插入模式
从命令行模式到插入模式:
1、按「i」切换进入插入模式「insert mode」,按“i”进入插入模式后是从光标当前位置开始输入文件。
2、按「a」进入插入模式后,是从目前光标所在位置的下一个位置开始输入文字。
3、按「o」进入插入模式后,是插入新的一行,从行首开始输入文字。
5、底行模式
底行模式下的命令:
1、set nu 或者 set nonu:调出或取消行号。
2、多屏操作
vs 文件名:就可以进入分屏操作模式。(光标在哪个分屏,就是可以操作的文件)。
ctrl + w(按两次):切换操作屏。
w:写入 q:退出。
:!命令:可以执行Linux下的命令(ll,man,./a.out,g++等)。在底行模式下还可以输入命令进行编译(g++)和运行。
6、vim 的配置
没有配置的vim用起来其实和记事本并没有多大的区别,不能自动补齐,也不能自动缩进,使用起来不是很方便。所以vim实际上是需要配置的。
但是配置vim比较麻烦,配置的东西比较多,作为刚入门的我们并不知道需要配置哪些东西,所以我们直接在家目录下执行一键配置的命令即可:
curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh
二、编译器gcc/g++
1、概念
gcc(g++)是一个专门用来编译链接C语言(C++)的编译器。
gcc只能编译c语言,g++可以编译c语言和c++。
2、背景知识
程序翻译的过程,本质上是将文本的C语言或其他语言转成计算机能够识别的二进制。转换过程:
1、预处理:去注释,进行宏替换,头文件展开,条件编译等。
2、编译:生成汇编语言(将C语言等语言编译成汇编语言)。
3、汇编:将汇编语言转换成可重定向二进制目标文件。
4、连接:生成可执行文件或库文件。将多个 .o文件(Linux下) 或 .obj(Windows下) 文件合并形成一个可执行文件 .exe(windows下)。
注:编译过程为 扫描程序-->语法分析-->语义分析-->源代码优化-->代码生成器-->目标代码优化。
1、扫描程序进行词法分析,从左向右,从上往下扫描源程序字符,识别出各个单词,确定单词类型。
2、语法分析是根据语法规则,将输入的语句构建出分析树,或者语法树,也就是分析树parse tree或者语法树syntax tree。
3、语义分析是根据上下文分析函数返回值类型是否对应这种语义检测,可以理解语法分析就是描述一个句子主宾谓是否符合规则,而语义用于检测句子的意思是否是正确的。
4、目标代码生成指的是,把中间代码变换成为特定机器上的低级语言代码。
3、gcc/g++中的编译链接
同样地,gcc/g++下也需要像上面那样一步一步形成最终的可执行文件。
语法:gcc 要编译的文件 -o 自己命名的可执行文件。如下:绿色的就是可执行文件。
zdl.c中的内容:
代码里面有宏,有头文件,有注释,有条件编译,可以验证我们接下来的内容。
1、预处理
但是,其实上面的做法是直接一步到位,直接形成了可执行程序。而我们为了验证gcc/g++是否会走上面的步骤,我们需要一步一步来看。所以我们要使用下面的命令:
gcc -E zdl.c -o test.i
-E:从现在开始,进行程序的翻译,如果预处理完成,就停下来。
上面的命令表示我们将预处理完成之后形成的内容写到了一个临时文件 test.i。所以预处理的内容(还是C语言)就在test.i中。如下:
我们发现842行的宏被替换了,注释也没有了,条件编译也执行了,头文件也展开了。
2、编译
接着我们执行下面的命令:将预处理完成的代码编译成汇编语言。
-S:从现在开始进行程序的翻译,如果编译完成,就停下来。
gcc -S test.i -o test.s
test.s就是汇编文件。
上图就是编译完成后汇编文件内容。
3、汇编
然后我们执行下面的命令:
gcc -c test.s -o test.o
-c:从现在开始进行程序的翻译,如果汇编完成,就停下来。
形成了二进制文件。test.o就是可重定向二进制目标文件。
我截取了其中一部分来看一看:
上图就是二进制文件的部分内容。
4、链接
最后对可重定向二进制目标文件进行链接,使用如下命令:
gcc test.o -o mytest
上图中,mytest就是最终的可执行程序,以及其执行结果。
4、函数库
首先,我们知道C/C++都有自己的标准库。
我们来看一个问题:在我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?
答案就是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。
这些库文件是现成的,是已经实现好了的,我们可以直接使用。当我们使用库中函数的时候,其中我们自己只是调用了该函数,没有真正地实现它,只有当链接的时候,对应的实现,才能和我们的代码关联起来。
一般链接的过程,有两种方式:1、动态链接(要动态库)2、静态链接(要静态库)。
1、静态库
静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”
静态链接:将库中方法的实现真的拷贝到我们的可执行程序中。
2、动态库
动态库是指在编译链接时,并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。
动态链接:将库中我要的方法的地址,填入我的可执行程序中,建立关联。