程序开发过程中,源代码的编辑主要是为了实现算法,结果则是一些可阅读的、便于检错的、可移植的文本文件。如何产生一份良好的源代码,这不仅需要一些良好的编辑工具,还需要开发人员养成良好的编程修养。
Linux 下有很多优秀的程序编辑工具,包括专业的文本编辑器和一些集成开发环境(IDE)提供的编辑工具,前者的代表作有 Vim 和 Emacs,后者的代表作则有 Eclipse,Kdevelop,Anjuta 等,这里主要介绍 Vim 的基本使用和配置。
通过 Vim 进行文本编辑的一般过程包括:文件的打开、编辑、保存、关闭/退出,而编辑则包括插入新内容、替换已有内容、查找内容,还包括复制、粘贴、删除等基本操作。
该过程如下图:
下面介绍几个主要操作:
在命令行下输入 vim 文件名 即可打开一个新文件并进入 Vim 的“编辑模式”。
vim 文件名
编辑模式可以切换到命令模式(按下字符 :)和插入模式(按下字母 a/A/i/I/o/O/s/S/c/C 等或者 Insert 键)。
:
a/A/i/I/o/O/s/S/c/C
编辑模式下,Vim 会把键盘输入解释成 Vim 的编辑命令,以便实现诸如字符串查找(按下字母 /)、文本复制(按下字母 yy)、粘贴(按下字母 pp)、删除(按下字母 d 等)、替换(s)等各种操作。
/
yy
pp
d
s
当按下 a/A/i/I/o/O/s/S/c/C 等字符时,Vim 先执行这些字符对应命令的动作(比如移动光标到某个位置,删除某些字符),然后进入插入模式;进入插入模式后可以通过按下 ESC 键或者是 CTRL+C 返回到编辑模式。
CTRL+C
在编辑模式下输入冒号 : 后可进入命令模式,通过它可以完成一些复杂的编辑功能,比如进行正则表达式匹配替换,执行 Shell 命令(按下 ! 命令)等。
!
实际上,无论是插入模式还是命令模式都是编辑模式的一种。而编辑模式却并不止它们两个,还有字符串查找、删除、替换等。
需要提到的是,如果在编辑模式按下字母 v/V 或者是 CTRL+V,可以用光标选择一个区块,进而结合命令模式对这一个区块进行特定的操作。
v/V
CTRL+V
打开文件以后即可进入编辑模式,这时可以进行各种编辑操作,包括插入、复制、删除、替换字符。其中两种比较重要的模式经常被“独立”出来,即上面提到的插入模式和命令模式。
在退出之前需切换到命令模式,输入命令 w 以便保存各种编辑后的内容,如果想取消某种操作,可以用 u 命令。如果打开 Vim 编辑器时没有设定文件名,那么在按下 w 命令时会提示没有文件名,此时需要在 w 命令后加上需要保存的文件名。
w
u
保存好内容后就可退出,只需在命令模式下键入字符 q。如果对文件内容进行了编辑,却没有保存,那么 Vim 会提示,如果不想保存之前的编辑动作,那么可按下字符 q 并且在之后跟上一个感叹号!,这样会强制退出,不保存最近的内容变更。
q
这里需要着重提到的是 Vim 的命令模式,它是 Vim 扩展各种新功能的接口,用户可以通过它启用和撤销某个功能,开发人员则可通过它为用户提供新的功能。下面主要介绍通过命令模式这个接口定制 Vim 以便我们更好地进行源代码的编辑。
先提一下编码风格。刚学习编程时,代码写得很“难看”(不方便阅读,不方便检错,看不出任何逻辑结构),常常导致心情不好,而且排错也很困难,所以逐渐意识到代码编写需要规范,即养成良好的编码风格,如果换成俗话,那就是代码的排版,让代码好看一些。虽说“编程的“(高雅一些则称开发人员)不一定懂艺术,不过这个应该不是“搞艺术的”(高雅一些应该是文艺工作人员)的特权,而是我们应该具备的专业素养。在 Linux 下,比较流行的“行业”风格有 KR 的编码风格、GNU 的编码风格、Linux 内核的编码风格(基于 KR 的,缩进是 8 个空格)等,它们都可以通过 indent 命令格式化,对应的选项分别是-kr,-gnu,-kr -i8。下面演示用 indent 命令把代码格式化成上面的三种风格。
indent
-kr
-gnu
-kr -i8
这样糟糕的编码风格看着会让人想“哭”,太难阅读啦:
$ cat > test.c /* test.c -- a test program for using indent */ #include<stdio.h> int main(int argc, char *argv[]) { int i=0; if (i != 0) {i++; } else {i--; }; for(i=0;i<5;i++)j++; printf("i=%d,j=%d\n",i,j); return 0; }
格式化成 KR 风格,好看多了:
$ indent -kr test.c $ cat test.c /* test.c -- a test program for using indent */ #include<stdio.h> int main(int argc, char *argv[]) { int i = 0; if (i != 0) { i++; } else { i--; }; for (i = 0; i < 5; i++) j++; printf("i=%d,j=%d\n", i, j); return 0; }
采用 GNU 风格,感觉不如 KR 的风格,处理 if 语句时增加了代码行,却并没明显改进效果:
if
$ indent -gnu test.c $ cat test.c /* test.c -- a test program for using indent */ #include<stdio.h> int main (int argc, char *argv[]) { int i = 0; if (i != 0) { i++; } else { i--; }; for (i = 0; i < 5; i++) j++; printf ("i=%d,j=%d\n", i, j); return 0; }
实际上 indent 命令有时候会不靠谱,也不建议“先污染再治理”,而是从一开始就坚持“可持续发展”的观念,在写代码时就逐步养成良好的风格。
需要提到地是,Linux 的编码风格描述文件为内核源码下的 Documentation/CodingStyle,而相应命令为 scripts/Lindent。
从演示中可看出编码风格真地很重要,但是如何养成良好的编码风格呢?经常练习,遵守某个编码风格,一如既往。不过这还不够,如果没有一个好编辑器,习惯也很难养成。而 Vim 提供了很多辅助我们养成良好编码习惯的功能,这些都通过它的命令模式提供。现在分开介绍几个功能;
:syntax on
:syntax off
:set cindent
set cin
:set sw=8
:set ts=8
:set number
:set nonumber
:setsm
这几个命令对代码编写来说非常有用,可以考虑把它们全部写到 ~/.vimrc 文件(Vim 启动时会去加载这个文件里头的内容)中,如:
~/.vimrc
$ cat ~/.vimrc :set number :set sw=8 :set ts=8 :set sm :set cin :syntax on
需要补充的几个技巧有;
对注释自动断行
gqap
set textwidth=个数
跳到指定行
vim +数字 文件名
把 C 语言输出为 html
TOhtml
syntax on
注释掉代码块
v
s#^#//#g
切换到粘贴模式解决 Insert 模式自动缩进的问题
set paste
set nopaste
使用 Vim 最新特性
set nocp
全局替换某个变量名
%s#old_variable#new_variable#g
%s#\<old_variable\>#new_variable#g
把缩进和 TAB 键都替换为空格
expandtab
set et
retab
关键字自动补全
CTRL+P
CTRL+N
prin
CTRL+P/N
在编辑模式下查看手册
Shift+k
man
删除空行
g/^$/d
g
%s#^\n##g
g/^\n$/d
%s#^\n$##g
创建与使用代码交叉引用
ctags
cscope
回到原位置
CTRL+T
这里特别提到 cscope,为了加速代码的阅读,还可以类似上面在 ~/.vimrc 文件中通过 map 命令预定义一些快捷方式,例如:
map
if has("cscope") set csprg=/usr/bin/cscope set csto=0 set cst set nocsverb " add any database in current directory if filereadable("cscope.out") cs add cscope.out " else add database pointed to by environment elseif $CSCOPE_DB != "" cs add $CSCOPE_DB endif set csverb :map \ :cs find g <C-R>=expand("<cword>")<CR><CR> :map s :cs find s <C-R>=expand("<cword>")<CR><CR> :map t :cs find t <C-R>=expand("<cword>")<CR><CR> :map c :cs find c <C-R>=expand("<cword>")<CR><CR> :map C :cs find d <C-R>=expand("<cword>")<CR><CR> :map f :cs find f <C-R>=expand("<cword>")<CR><CR> endif
因为 s,t,c,C,f 这几个 Vim 的默认快捷键用得不太多,所以就把它们给作为快捷方式映射了,如果已经习惯它们作为其他的快捷方式就换别的字符吧。
s,t,c,C,f
注 上面很多技巧中用到了正则表达式,关于这部分请参考:正则表达式 30 分钟入门教程。
更多的技巧可以看看后续资料。
实际上,在源代码编写时还有很多需要培养的“素质”,例如源文件的开头注释、函数的注释,变量的命名等。这方面建议看看参考资料里的编程修养、内核编码风格、网络上流传的《华为编程规范》,以及《C Traps & Pitfalls》, 《C-FAQ》等。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8