通常使用的如VS2019等工具,具有以下特点
类似的这种工具叫做IDE:集成开发环境
相比之下,vim的功能就简单得多
vim是一款纯编辑器:只负责写代码
vim test.c
:用vim打开test.c
vim
:打开vim
默认打开后 按键不能编辑文件内容,这是因为默认打开是命令模式
vim常见有几种模式:
命令模式:
也叫普通模式或者正常模式
编辑/插入模式:
在此模式下可以进行编辑代码
底行模式:
查看所有的模式:vim
命令来进入vim,然后底行模式输入 help vim-modes
#模式的切换
vim test.c
就进入vim编辑画面,模式是[正常模式]需要切换到[插入模式]才可以输入文字
[命令模式] 切换至 [插入模式]
[插入模式] 切换至 [命令模式]
[命令模式] 切换至 [底行模式]
shift + ;
其实就是 :
[底行模式] 切换至 [命令模式]
vim的退出以及保存工作
(以下的 : 表示在底行模式下)
#复制粘贴
yy
:复制光标所在的行
p
:对复制的内容进行复制
yy
+ p
:可以复制一行,按一次p复制一行
yy + np
:n为具体数字,按一次p复制 n行(如n为1000 就是复制1000行)
例子:复制一行,粘贴3次
nyy
+ p
:n为具体数字,复制从光标所在行开始向下的n行,然后粘贴一次
例子:复制4行,粘贴1次
nyy
+mp
:n和m为具体数字,复制从光标所在行开始向下的n行,然后粘贴m次
#撤销与反撤销
在命令模式下
u
:撤销刚才的操作
Ctrl + r
:撤销刚才的撤销操作
注意:一旦关闭文件,下一次进入文件就没有办法撤销了
#光标定位
上下定位
shift + g
:光标定位到文件的末尾
gg
:光标定位到文件的最开始
n + shift + g
:光标定位到第n行
左右定位
shift + 6
(^):光标定位到当前行的最开始
shift + 4
($):光标定位到当前行的最结尾
左右箭头按键
一行中左右移动(以字符为单位)
w
:以单词为单位向后移动
b
:以单词为单位向前移动
nw
:n为数字,向后移动n个单词
nb
:n为数字,向前移动n个单词
其他定位
h j k l
:表示上下左右
h
:向左
j
:向下
k
:向上
l
:向右
#文本删除和剪切
dd
:删除光标所在行
ndd
:删除从光标开始向下的n行
dd
+p
:剪切所在行,按p粘贴
ndd
+p
:剪切n行,然后粘贴
#字母大小写转换
shift + ~
:转换成大写/小写(如果是大写就转换成小写,小写就转化成大写)
#替换文本
这里需要进入一种新的模式:替换模式
直接替换文本
shift + r
:进入替换模式
此时就会从光标处开始替换文本:输入什么替换什么
(注意左下角已经进入了replace模式)
只替换一个字符
r
+ 替换的字符(每一次都需要按一次r
再按要替换的字符)
一次替换多个字符
nr
+ 替换的字符(n为一个数字表示一次替换字符的个数)
如图:一次替换四个w 和 x
#删除字符
删除一个字符
x
:删除光标位置的字符(从左向右删)
注意:作用在此行
删除多个字符
nx
:删除n个字符(从左向右)
注意:
shift + x
(X) :删除当前光标的前一个字符(从右向左)n shift + x
:删除n个字符(从右向左)这两个与上面的x用法相同
set nu
:设置行号
set nonu
:取消行号
在vim中可以同时打开多个文件进行编辑
vim test.c
打开一个文件后
: vs test1.c
:底行命令打开另一个文件
写入内容:(光标在哪就在哪里写)
#光标在不同的屏幕之间切换
Ctrl + ww
:(Ctrl
按住不懂,w
快速按两下)
可以在右边的文件中进行复制,然后粘贴到左边的文件中
:!cmd
:直接在vim中执行Linux命令而不会退出vim(回车返回)
如:! ls -al
:在vim中执行ls -al命令
好处:
在用户的家目录下cd ~
,创建一个文件夹 .vimrc
这里面包含了对vim的配置,比如显示行号、代码自动补齐、缩进字符数等
这些配置可以在网上搜索到,然后Ctrl+c
,Ctrl+v
到.vimrc
中即可
或者直接用yum
命令安装人家写好的配置文件即可
vimforcpp
就是一个不错的选择
安装:
curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh
卸载:
bash ~/.VimForCpp/uninstall.sh
很多时候,我们需要用到root的权限
但是,普通用户不在信任列表,就不可以添加执行sudo语句
那么如何添加用户到信任列表?
切换成root用户
vim打开 /etc/sudoers
文件(只有root能打开)
然后找到107行左右
如图 在后面添加 用户名 ALL=(ALL) ALL
即可
然后切换到底行模式,w!``q!
(强制保存,强制退出)即可
gcc是一个专门用来编译链接C语言的编译器
g++则是编译链接C++,也可以编译链接C语言
注意:gcc不能编译C++
一般gcc都有,但是如果g++没有
安装g++:sudo yum install -y gcc-c++
查看版本:gcc -v
、g++ -v
因为硬件的底层,是靠电路的正和负两种状态来实现的,对应就是0和1.所以计算机只认识二进制
程序翻译的过程实际上就是把程序转化成二进制的过程
预处理 (.c -> .i)
注意:预处理之后还是C语言
编译
C/C++ -> 汇编语言 (.s)
汇编
汇编语言 -> 可重定向二进制目标文件(.o / .obj)
链接
多个.o / .obj -> 合并成一个可执行文件 (.exe)
gcc默认一步到位生成可执行程序
gcc test.c
:直接生成可执行文件,默认名:a.out
gcc test.c -o test
:生成叫test的可执行文件
也可以这样写:gcc -o test test.c
注意:-o 后面紧跟 要形成的文件名
预处理 (.c -> .i)
gcc -E mytest.c
:把预处理完成生成的内容 .i文件
打印到屏幕
gcc -E mytest.c -o mytest.i
:把预处理生成的内容.i文件
保存到 mytest.i 文件
-o : 就是指定一个新的名字
-E:从现在开始进行程序的翻译,如果预处理完成,就停下来
编译
gcc -S mytest.i -o mytest.s
:生成.s文件(汇编代码)
-S:从现在开始进行程序的翻译,如果编译完成,就停下来
汇编
gcc -c mytest.c -o mytest.o
:生成.o文件(可重定向二进制目标文件),里面都是二进制
-c:从现在开始进行程序的翻译,如果汇编完成就停下来
可以用od mytest.o
查看二进制文件
链接
gcc mytest.o -o mytest
:链接生成可执行文件mytest
巧记
过程:E S c -> 对应键盘的ESC建
文件:i s o -> 镜像文件的后缀
g++的过程和 gcc的程序翻译过程是一样的
链接阶段,其实有一个重要的概念:函数库
[[对库的认识]]
写C/C++程序时,通常的做法是
func.h
中包含自己写的函数的声明
func.cpp
中包含函数的定义
test.cpp
中测试代码
当test.cpp中包含了func.h文件后,也就是有了函数的声明。如果调用其中的函数,编译器就知道函数是存在的,会去别的地方找。
静态库/动态库与func.cpp的作用类似,包含了.h文件后,就去库中找对应的函数的实现,从而构成可执行程序
举个例子:
我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而
没有定义函数的实现,那么,是在哪里实“printf”函数的呢?
最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用
所以C程序是离不开C库文件的
并且,Linux下很多命令也是直接利用C语言写的,比如ls命令
通过ldd /usr/bin/ls
就可以看到所依赖的库
函数库一般分为静态库和动态库两种,对应就有静态链接和动态链接
动态库:
在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销(也就是在本文件中加载所调用函数的地址,去调用)
静态库:
直接把库文件对应函数的代码全部加入到可执行程序中,因此生成的文件比较大,但在运行时也就不再需要库文件了
所以一般链接的过程有两种方式
[[动态库和静态库在不同系统的后缀]]
Linux下:.so(动态库),.a(静态库)
Windows下:.dll(动态库) ,.lib(静态库)
所以在安装VS2019等软件的时候,一并安装了C标准库的头文件和C标准库文件
链接之后,生成了可执行文件,我们可以查看生成的可执行文件的信息:ldd mytest
,file mytest
其实最后生成的可执行文件 ,本身也是依赖于C语言的库的
如图可见 可执行文件的信息:
汇编之后生成的.o文件已经是二进制了,为什么不能执行?
因为:生成的.o文件是自己写的代码翻译成了二进制的形式,但是你自己的代码中还有一些没有和库关联起来。调用的函数需要和库关联起来才能形成可执行文件。
其实就是 调用函数,实际上需要调用函数的地址,而如果不关联,就找不到函数的地址(是未定义的),自然就报错
静态库:
动态库:
总的来说静态库是牺牲了空间效率,换取了时间效率,共享库是牺牲了时间效率换取了空间效率,没有好与坏的区别,只看具体需要了。
gcc和g++默认形成的可执行程序是动态链接的
事实上,动态链接形成可执行几乎是所有编译器的默认行为
(可以通过 ldd
和 file
命令查看)
如何静态链接呢?
gcc tesc.c -o mytest_s -static
: 生成采用静态链接的可执行文件 mytest_s(自定义命名即可,这里用s表示静态)
-static
:表示用静态链接的方法形成可执行程序
可以看到采用静态链接生成的可执行文件的大小 远大于 采用动态链接生成的可执行程序的大小(将近100倍)
注意:
动态链接必须使用.so动态库文件
静态链接必须使用.a静态库文件
而云服务器一般只有动态库没有静态库,如果使用静态库就会导致链接失败,需要安装
C静态库的安装:sudo yum install -y glibc-static
C++静态库的安装:sudo yum install -y libstdc++-static