vim
三种模式的转换:
*命令模式 *
插入:进入输入模式
- i:在光标前进行输入
- a:在光标后进行输入
- I:在光标所在行首进行输入
- A:在光标所在行尾进行输入
- o:在光标下一行进行输入
- O:在光标上一行进行输入
删除:其实是剪切到缓冲区
- 删除单个字符:x(删的是光标上的那个字符)
- 删除一个单词:dw(光标必须处于这个单词的第一个字母)
- 删除光标至行尾:D或者d$(光标所在处字符也会被删除)
- 删除光标至行首:d0(光标所在处字符不会被删除)
- 删除指定1行:dd
- 删除指定n行:ndd
- 删除指定区域:按V切换为可视模式,移动光标来选中待删除区域,再按 d 删除该区域
移动光标:
- 上下左右:小键盘方向键或者hjkl
- 移至行首:0
- 移至行尾:$
跳转到指定行:
- 跳到首行:gg
- 跳到末行:G
- 跳到指定行:25G(或者在末行模式下可以通过:25来进行跳转)
复制粘贴剪切:
- 复制本行:yy
- 复制多行:nyy
- 复制指定区域:按V切换为可视模式,移动光标来选中待复制区域,再按 yy复制该区域
- 粘贴:p(粘贴到光标后)、P(粘贴到光标前)
- 剪切:删除就会将内容剪切到缓冲区
查找:
- 关键字查找:按/输入搜索关键字,回车,再按n显示下一个搜索结果
- 文中重复内容查找:将光标置于单词任意一个字符上,按*或者#
撤销修改:u
反向撤销修改:ctrl + r
自动格式排版:gg=G
找到对应的另一半大括号:将光标移动到其中一个大括号,按下%即可跳转到另一个大括号
跳转至 man 帮助手册:将光标置于待查看函数单词上,按下K跳转(指定卷:nK)
查看宏定义:将光标置于待查看宏定义单词上,按下[d
查看定义语句
函数跳转:将光标置于函数名上,按Ctrl-]
进行跳转(需要ctags工具,详见下一篇博文)
*末行模式*
替换:
- 单个字符替换:将光标置于待替换字符上, 按r进行替换(注意要在命令模式下执行)
- 单行替换:将光标置于待替换行上,进入末行模式,输入:s/原数据/新数据
- 通篇替换:末行模式下,输入 :%s /原数据/新数据/g
- 指定行的替换:末行模式,:起始行号,终止行号s /原数据/新数据/g
分屏:
- 竖屏:
vsp
(分屏可以直接新建或打开文件,比如:vsp sub.c
) - 横屏:
sp
- 切换屏幕:
ctrl+ww
- 关闭分屏:
:q
(如果要一次性关闭所有分屏并保存:wqall
)
执行shell命令:!命令
gcc
gcc编译四步骤:预处理、编译、汇编、链接
gcc命令参数:
-o
:指定gcc编译结果文件名gcc hello.c -o hello
-I
:指定头文件所在目录位置gcc hello.c -o hello -I ./inc
-c
:只做预处理、编译、汇编,得到hello.o二进制文件gcc -c ./src/hello.c -o ./obj/hello -I ./inc
-g
:编译时添加调试语句,主要支持gdb调试gcc hello.c -o hello
–g
-Wall
:warning all,即显示所有警告信息-D
:向程序中“动态”注册宏定义gcc hello.c -o hello4 -D HONG
- –
l
:指定动态库名 -L
:指定动态库路径
程序库
简单来说,程序库是包含了数据和执行码的文件,本质是一组具有相似、相近功能函数的集合。可以作为其它执行程序的一部分来完成某些功能,但不能单独执行。程序库加快了程序的再编译,使得程序模块化并且便于升级。
程序库分为静态库和共享库(又叫动态库),静态库是在可执行程序运行前就已经加入到执行码中,成为执行程序的一部分,而共享库是在执行程序启动时(且调用到了共享库中的“函数”时)加载到执行程序中,可以被多个执行程序共享使用。静态库文件名一般以lib开头,以.a结尾,动态库文件名一般以.so结尾。
静态库:(了解即可)
- 机制:每个使用静态库的程序都要将整个静态库编译到可执行程序
- 优点:库函数本地化,调用速度快
- 缺点:消耗系统资源大
- 使用场景:适合对空间要求较低,而对时间要求较高的核心程序中
动态库:(重点)
- 机制:多个可执行程序共享一份库文件(共享代码、不共享数据)
- 优点:节省内存、易于更新
- 缺点:由于实现机制原因,较静态库函数调用相比速度慢
- 使用场景:适合对时间要求较低,而对空间要求较高的程序中
静态库制作及使用步骤:
- 将 .c 生成 .o 二进制文件
gcc -c add.c -o add.o
- 使用 ar 工具制作静态库
ar rcs libmymath.a add.o sub.o div1.o
- 编译静态库到可执行文件中
gcc test.c libmymath.a -o test.out
但这样会存在函数的隐性声明警告,因为函数在.c程序中既没定义(在静态库中),也没声明。最好新建一个mymath.h头文件,并在.c程序中引入。
头文件守卫:防止头文件被重复包含
完整步骤(from xiaobing1016):
动态库制作及使用步骤:
- 将 .c 生成 .o 二进制文件 (与制作静态库不同,要生成与位置无关的代码,参数为
-fPIC
)gcc -c add.c -o add.o -fPIC
- 使用 gcc -shared选项制作动态库
gcc -shared -o libmymath.so add.o sub.o div1.o
(注意这里的.o文件和制作静态库时不同,因为加了-fPIC
) - 编译可执行程序时,指定所使用的动态库。选项 -l 指定库名(去掉lib前缀和.so后缀), -L指定库路径。
gcc test.c -o a.out -l mymath -L ./lib
- 运行可以执行程序
./a.out
常见报错:./a.out: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory
原因: -l 和 -L 是给链接器用的,动态链接器找不到动态库的位置
- 链接器:工作于链接阶段,工作时需要
-l
和-L
- 动态链接器:工作于程序运行阶段,工作时需要提供动态库所在目录位置(报错原因)
解决方式:
- 临时生效:通过环境变量
export LD_LIBRARY_PATH=动态库路径
(终端重启环境变量失效) - 永久生效:将上述命令写入终端配置文件
.bashrc
,重启终端让修改后的.bashrc
生效 - 拷贝自定义动态库到
/lib
(标准C库所在目录位置) - 配置文件法:1)
sudo vi /etc/ld.so.conf
2) 写入动态库绝对路径 3)sudo ldconfig -v
使配置文件生效
动态库注意事项:
- 动态库是否加载到了内存,取决于程序是否运行
- 动态库每次加载的位置不固定
- 动、静态库共存时,编译器默认使用动态库
完整步骤(from xiaobing1016):