目录
Vim基本使用
Vim基本操作
i | 进入编辑模式,光标前插入字符 | I | 进入编辑模式,光标所在行的行首插入 |
a | 进入编辑模式,光标后插入字符 | A | 进入编辑模式,光标所在行的行末插入字符 |
o | 进入编辑模式,光标所在行的下一行插入 | O | 进入编辑模式,光标所在行的上一行插入字符 |
s | 删除光标所在字符并进入编辑模式 | S | 删除光标所在行并进入编辑模式 |
跳转操作
gg(命令模式) | 跳转文件首 | G(命令模式) | 跳转文件尾 |
0(命令模式) | 光标移至行首,工作模式不变 | $(命令模式) | 光标移至行尾,工作模式不变 |
gg=G(命令模式) | 自动格式化程序 | %(命令模式) | 大括号对应 |
删除操作
x(命令模式) | 删除单个字符,工作模式不变 | dw(命令模式) | 删除一个单词(光标置于单词的首字母进行操作) |
d0(命令模式) | 删除光标所在位置到行首,工作模式不变 | d$(命令模式) | 删除光标所在位置到行末,工作模式不变 |
dd(命令模式) | 删除光标所在行 | n+dd(命令模式) | 删除从光标开始的n行 |
r(命令模式) | 替换光标选中单个字符 | 按v进入可视模式,再使用hjkl移动到要删除的末尾,按d删除 | 删除指定区域 |
粘贴复制操作
yy | 复制光标所在行 | 小p | 向后粘贴剪切板内容,如果复制整行,这里是粘贴在光标所在位置的下一行 |
n-yy | 复制光标所在位置的n行,包括光标所在行 | 大P | 向前粘贴剪切板内容,如果是整行,这里是粘贴在光标所在位置的上一行 |
查找和替换操作
/+findname(命令模式) | 按回车键启动查找后,按n,会自动找下一个,N跳到上一个 | *或者# | 光标在目标单词上时,查找光标所在单词 |
:s /待替换词/替换词 | 光标置于待替换行,单行替换 | :24,35s /待替换词/替换词/g | 替换24-35行之间的目标词 |
:%s /待替换词/替换词 | 替换每行的首个,一行有多个目标词时,后面的不会变 | :%s /待替换词/替换词/g | 真正意义上的全局替换 |
Ctrl-p | 上一条命令 | Ctrl-n | 下一条命令 |
其他操作
命令模式下撤销操作 | |||
u | 撤销操作 | Ctrl-r | 反撤销 |
分屏操作,末行模式下 | |||
:sp | 水平分屏 | :vsp | 竖直分屏 |
分屏命令+filename | 分屏并打开这个文件 | Ctrl-w-w | 分屏后屏幕切换 |
:q | 退出光标所在窗口 | :qall | 退出所有窗口 |
从vim中跳转manpage,命令模式下 | |||
将光标放在待查看单词上,按K | 默认看第一卷 | n+K | 查看第n卷 |
查看宏定义:命令模式 | |||
[+d | 光标放在待查看词上,即可查看 | ||
vim下使用shell命令:末行模式 | |||
:! + 命令 |
打造个性化的Vim
两个Vim配置文件,第二个配置文件会优先加载,属于用户配置
/etc/vim/vimrc
~/.vimrc
gcc基本使用
gcc编译常用参数
gcc -I ./hellodir hello.c -o hello
当头文件和源码不在一个目录下时,需要指定头文件
其中-I参数指定头文件所在位置,位置可以在编译文件前,也可以在后面
-I 指定头文件所在目录位置
-c 只做预处理,编译,汇编。得到二进制文件 !!!!!!!
-g 编译时添加调试文件,用于gdb调试
-Wall 显示所有警告信息
-D 向程序中“动态”注册宏定义
-l 指定动态库库名
-L 指定动态库路径
静态库与动态库对比
<1>静态库在文件中静态展开,所以有多少文件就展开多少次,非常吃内存,100M展开100次,就是1G,但是这样的好处就是静态加载的速度快
<2>使用动态库会将动态库加载到内存,10个文件也只需要加载一次,然后这些文件用到库的时候临时去加载,速度慢一些,但是很省内存
静态库制作与使用
静态库名字以lib开头,以.a结尾
例如:libmylib.a
静态库制作及使用步骤:
1. 将 .c 生成 .o 文件
gcc -c add.c -o add.o
2. 使用 ar 工具制作静态库
ar rcs lib库名.a add.o sub.o div.o
3. 编译静态库到可执行文件(最好使用绝对路径)中:
gcc test.c lib库名.a -o a.out
注意:引用静态库时,原文件为声明库中函数会发生警告
原因:用编译器隐式声明来解决的
编译器只能隐式声明返回值为int的函数形式:int add(int ,int );
如果函数不是返回的int,则隐式声明失效,会报错
解决方案:
方案一:在原文件中添加函数声明
方案二:创建头文件,在头文件中添加函数声明
动态库
地址回填
<1>写在源代码里的函数,相对main函数偏移是一定的,链接时,回填main函数地址之后,其他源代码里的函数也就得到了地址。
<2>而动态库函数地址的确定是发生在运行时,只有动态库被加载后,该动态库函数的地址才会确定,也叫延时调用。动态库里的函数会用一个@plt来标识,当动态库加载到内存时,再用加载进去的地址将@plt替换掉。
数据段合并
数据段合并是将只读的代码区和存储区合并,还有将全局区的bss段,Data段合并,目的是节省空间。因为内存最小的开辟内存空间单位是页(page),一页=4k。
例如:代码区和存储区不合并,都存放1k的字节,但是由于最小开辟单位是一页,所以两个总共开辟8k。为了节省内存,合并之后就只需要开辟一页,节省了4k的内存。
动态库制作
制作动态库的步骤
1. 生成位置无关的.o文件
gcc -c add.c -o add.o -fPIC
使用这个参数过后,生成的函数就和位置无关,挂上@plt标识,等待动态绑定
2. 使用 gcc -shared制作动态库
gcc -shared -o lib库名.so add.o sub.o div.o
3. 编译可执行程序时指定所使用的动态库。-l:指定库名 -L:指定库路径
gcc test.c -o a.out -l mymath -L ./lib
4. 运行可执行程序./a.out
动态库首次加载错误原因及解决方案
出错原因分析
连接器: 工作于链接阶段,工作时需要 -l 和 -L
动态链接器: 工作于程序运行阶段,工作时需要提供动态库所在目录位置
解决方式
【1】 通过环境变量: export LD_LIBRARY_PATH=动态库路径
./a.out 成功!!! (临时生效, 终端重启环境变量失效)
环境变量时进程的概念,关闭终端之后再打开,是两个进程,环境变量发生了变化
【2】 永久生效: 写入 终端配置文件。 .bashrc 建议使用绝对路径。
1) vi ~/.bashrc
2) 写入 export LD_LIBRARY_PATH=动态库路径 保存
3). .bashrc/ source .bashrc / 重启 终端 ---> 让修改后的.bashrc生效
4)./a.out 成功!!!
【3】 拷贝自定义动态库 到 /lib (标准C库所在目录位置)
【4】 配置文件法
1)sudo vi /etc/ld.so.conf
2) 写入 动态库绝对路径 保存
3)sudo ldconfig -v 使配置文件生效,更新/etc/ld.so.cache文件。
4)./a.out 成功!!!--- 使用 ldd a.out 查看
注意事项:
<1>动态库是否加载到内存,取决于程序是否运行
<2>动态库每次加载的位置不固定
<3>动、静态库共存时,编译器默认使用动态库
gdb调试工具
使用-g编译可以执行文件,得到调试表
gcc -g main.c -o main
启动gdb
方式一:gdb main
方式二:gdb -q main //表示不打印gdb版本信息,界面较为干净
常用指令
list: list 行号 列出源码。根据源码指定 行号设置断点。默认每次显示10行
break/b:b 20 在20行位置设置断点。
run/r: 运行程序
n/next: 下一条指令(会越过函数)
s/step: 下一条指令(会进入函数)
p/print:p i 查看变量的值。
continue:继续执行到下一断点。
finish:结束当前函数调用。
quit/q:退出gdb当前调试。
其他指令
run:使用run查找段错误出现位置。
set args: 设置main函数命令行参数 (在 start、run 之前)
run argv[1] argv[1] ...: 设置main函数命令行参数
info b: 查看断点信息表
b 20 if i = 5: 设置条件断点。
ptype:查看变量类型。
bt:列出当前程序正存活着的栈帧。
frame: 根据栈帧编号,切换栈帧。
display:设置跟踪变量
undisplay:取消设置跟踪变量。 使用跟踪变量的编号。
1、运行命令
run:简记为 r ,其作用是运行程序,当遇到断点后,程序会在断点处停止运行,等待用户输入下一步的命令。
continue (简写c ):继续执行,到下一个断点处(或运行结束)
next:(简写 n),单步跟踪程序,当遇到函数调用时,也不进入此函数体;此命令同 step 的主要区别是,step 遇到用户自定义的函数,将步进到函数中去运行,而 next 则直接调用函数,不会进入到函数体内。
step (简写s):单步调试如果有函数调用,则进入函数;与命令n不同,n是不进入调用的函数的 until:当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。
until+行号: 运行至某行,不仅仅用来跳出循环
finish: 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息。
call 函数(参数):调用程序中可见的函数,并传递“参数”,如:call gdb_test(55)
quit:简记为 q ,退出gdb
2、设置断点
break n (简写b n):在第n行处设置断点
(可以带上代码路径和代码名称: b OAGUPDATE.cpp:578)
b fn1 if a>b:条件断点设置
break func(break缩写为b):在函数func()的入口处设置断点,如:break cb_button
delete 断点号n:删除第n个断点
disable 断点号n:暂停第n个断点
enable 断点号n:开启第n个断点
clear 行号n:清除第n行的断点
info b (info breakpoints) :显示当前程序的断点设置情况
delete breakpoints:清除所有断点:
3、查看源码
list :简记为 l ,其作用就是列出程序的源代码,默认每次显示10行。
list 行号:将显示当前文件以“行号”为中心的前后10行代码,如:list 12
list 函数名:将显示“函数名”所在函数的源代码,如:list main
list :不带参数,将接着上一次 list 命令的,输出下边的内容。
4、打印表达式
print 表达式:简记为 p ,其中“表达式”可以是任何当前正在被测试程序的有效表达式,比如当前正在调试C语言的程序,那么“表达式”可以是任何C语言的有效表达式,包括数字,变量甚至是函数调用。
print a:将显示整数 a 的值
print ++a:将把 a 中的值加1,并显示出来
print name:将显示字符串 name 的值
print gdb_test(22):将以整数22作为参数调用 gdb_test() 函数
print gdb_test(a):将以变量 a 作为参数调用 gdb_test() 函数
display 表达式:在单步运行时将非常有用,使用display命令设置一个表达式后,它将在每次单步进行指令后,紧接着输出被设置的表达式及值。如: display a
watch 表达式:设置一个监视点,一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。如: watch a
whatis :查询变量或函数
info function: 查询函数
扩展info locals: 显示当前堆栈页的所有变量
5、查看运行信息
where/bt :当前运行的堆栈列表;
bt backtrace 显示当前调用堆栈
up/down 改变堆栈显示的深度
set args 参数:指定运行时的参数
show args:查看设置好的参数
info program: 来查看程序的是否在运行,进程号,被暂停的原因。
6、分割窗口
layout:用于分割窗口,可以一边查看代码,一边测试:
layout src:显示源代码窗口
layout asm:显示反汇编窗口
layout regs:显示源代码/反汇编和CPU寄存器窗口
layout split:显示源代码和反汇编窗口
Ctrl + L:刷新窗口
Makefile项目管理
一个规则
目标:依赖条件
(一个tab缩进)命令
hello:hello.c
gcc hello.c -o hello
<1>目标的时间必须晚于依赖条件的时间,否则,更新目标
<2>依赖条件如果不存在,找寻新的规则去产生依赖条件。
<3>makefile默认第一行的目标为最终目标,执行完即结束,可使用ALL:目标 指定最终目标
两个函数和clean
src = $(wildcard *.c)
匹配当前工作用户下的所有.c文件。将文件名组成列表,赋值给变量src。
找到当前目录下所有后缀为.c的文件,赋值给src
obj = $(patsubset %.c,%.o, $(src))
将参数3中,包含参数1的部分,替换成参数2
把src变量里所有后缀为.c的文件替换成.o
clean:没有依赖
-rm -rf $(obj) a.out
"-":作用是,删除不存在文件时,不报错。顺序执行结束
三个自动变量
$@ :在规则命令中,表示规则中的目标
$< :在规则命令中,表示规则中的第一个条件,如果将该变量用在模式规则
中,它可以将依赖条件列表中的依赖依次取出,套用模式规则
$^ :在规则命令中,表示规则中的所有条件,组成一个列表,以空格隔开,
如果这个列表中有重复项,则去重
模式规则:
%.o:%.c
gcc -c $< -o $@
优化makefile,使用静态模式规则,就是指定模式规则给谁用,这里指定模式规则
给obj用,以后文件多了,文件集合会有很多个,就需要指定哪个文件集合用什么规则
$(obj):%.o:%.c
gcc -c $< -o $@
注意:当前文件夹下有ALL文件或者clean文件时,会导致makefile瘫痪,如下所示,
make clean没有工作用伪目标来解决,添加一行:
.PHONY: clean ALL
参数:
make -n或make clean -n:模拟执行make或make clean命令
make -f m1:指定文件执行make命令
ctags基本使用
ctags是vim下方便代码阅读的工具
安装
ubuntu直接安装
sudo apt-get install exuberant-ctags
安装检验
ctags --version
//安装aptitude
sudo apt-get install aptitude
//推荐使用
sudo aptitude show exuberant-ctags
使用
ctags –R . 上面介绍过了,不再赘述
Ctrl+ ] 跳到光标所在变量的定义处
Ctrl+ t 返回查找或跳转,从哪里跳过来的跳回哪里,即使用了很多次 Ctrl+],该命令也会回到最初一次的位置
vi –t tag 找到名为 tag 的变量的定义处
g] 列出变量的所有引用供用户选择
:ts tagslist,同 g]
:tp tagspreview,上一个tag标记文件
:tn tagsnext),下一个tag标记文件