转自:http://learn.akae.cn/media/ch09.html
代码风格好不好就像字写得好不好看一样,如果一个公司招聘秘书,肯定不要字写得难看的,同理,代码风格糟糕的程序员肯定也是不称职的。虽然编译器不会挑剔难看的代码,照样能编译通过,但是和你一个team的其他程序员肯定受不了,你自己也受不了,写完代码几天之后再来看,自己都不知道自己写的是什么。Structureand
Interpretation of Computer Programs里有句话说得好:“Thus,programs must bewritten for people to read, and only incidentally formachines toexecute.”代码主要为了是写给人看的,而不是写给机器看的,只是顺便也能用机器执行而已,如果是为了写给机器看那直接写机器码就好了,没必要用高级语言了。代码和语言文字一样是为了表达思想、记载信息,所以一定要写得清楚整洁才能有效地表达。正因为如此,在一个软件项目中,代码风格一般都用文档规定死了,所有参与项目的人不管他自己原来是什么风格,都要遵守统一的风格,例如Linux内核的Linux内核源代码的Documentation/CodingStyle就是这样一个文档。我们以内核为例来讲解编码风格的概念,并没有说内核风格就一定是最好的编码风格,但Linux内核项目如此成功,足以说明它的编码风格是最好的C语言编码风格之一了。
-
缩进和空白
-
关键字if,while, for与其后的控制表达式的(括号之间插入一个空格分隔,但括号内的表达式应紧贴括号。
-
双目运算符的两侧插入一个空格分隔,单目运算符和操作数之间不加空格。
-
后缀运算符和操作数之间也不加空格,例如取结构体成员s.a、函数调用foo(arg1)、取数组成员a[i]。
-
,号和;号之后要加空格,这是英文的书写习惯,例如for(i=1; i<10; i++)、foo(arg1,arg2)。
-
以上关于双目运算符和后缀运算符的规则不是严格要求,有时候为了突出优先级也可以写得更紧凑一些,例如for(i=1; i<10; i++)、distance= sqrt(x*x + y*y)等。但是省略的空格一定不要误导了读代码的人,例如a||b&&
c很容易让人理解成错误的优先级。
-
由于标准的Linux终端是24行80列的,接近或大于80个字符的较长语句要折行写,折行后用空格和上面的表达式或参数对齐。
-
较长的字符串可以断成多个字符串然后分行书写,例如:
printf("Thisis such a long sentence that "
"itcannot be held within a line\n");
C编译器会自动把相邻的多个字符串接在一起,以上两个字符串相当于一个字符串"Thisissuch
a long sentence that it cannot be held within a line\n"。
-
有的人喜欢在变量定义语句中用Tab字符,使变量名对齐,这样看起来也很好,但不是严格要求的。
内核关于缩进的规则有以下几条。
-
要用缩进体现出语句块的层次关系,使用Tab字符缩进,不能用空格代替Tab。在标准的Linux终端上,一个Tab看起来是8个空格的宽度,有些编辑器可以设置一个Tab看起来是几个空格的宽度,建议设成8,这样大的缩进使代码看起来非常清晰。规定不能用空格代替Tab主要是不希望空格和Tab混在一起做缩进,如果混在一起用了,在某些编辑器里把Tab的宽度改了就会看起来非常混乱。
-
if/else、while、do/while、for、switch这些可以带语句块的语句,语句块的{和}应该和关键字写在一起,用空格隔开,而不是单独占一行。内核的写法和TheC
ProgrammingLanguage一致,好处是不必占用太多空行,使得一屏能显示更多代码。这两种写法用得都很广泛,只要在同一个项目中能保持统一就可以了。
-
函数定义的{和}单独占一行,这一点和语句块的规定不同。
-
switch和语句块里的case、default对齐写,也就是说语句块里的case、default相对于switch不往里缩进。
-
自己命名的标号(用于goto)必须顶头写不缩进,而不管标号下的语句缩进到第几层。
-
代码中每个逻辑段落之间应该用一个空行分隔开。例如每个函数定义之间应该插入一个空行,头文件、全局变量定义和函数定义之间也应该插入空行。
-
一个函数的语句列表如果很长,也可以根据相关性分成若干组,用空行分隔,这条规定不是严格要求,一般变量定义语句组成一组,后面要加空行,return之前要加空行
-
标识符命名
标识符命名应遵循以下原则:
-
标识符的命名要清晰明了,可以使用完整的单词和大家易于理解的缩写。短的单词可以通过去元音形成缩写,较长的单词可以取单词的头几个字母形成缩写,也可以采用大家基本认同的缩写。例如count写成cnt,block写成blk,length写成len,window写成win,message写成msg,temporary可以写成temp,也可以进一步写成tmp。
-
内核风格规定变量、函数和类型采用全小写加下划线的方式命名,常量(宏定义和枚举常量)采用全大写加下划线的方式命名。上面举例的函数名radix_tree_insert、类型名structradix_tree_root、常量名RADIX_TREE_MAP_SHIFT等。有一种变量命名风格叫匈牙利命名法(Hungariannotation),用变量名的前缀记录变量的类型,例如iCnt、pMsg、lpszBlk等,Linus在Linux内核源代码的Documentation/CodingStyle中毫不客气地讽刺了微软发明的这一风格:“Encodingthe
type of a function into the name (so-called Hungarian notation)isbrain damaged - the compiler knows the types anyway and can checkthose, and it onlyconfuses the programmer. No wonder MicroSoftmakes buggyprograms.”代码风格本来就是一个很有争议的问题,如果你接受本章介绍的内核风格,就不要使用大小写混合的变量命名方式[17],更不要使用匈牙利命名法。
-
全局变量和全局函数的命名一定要详细,不惜多用几个单词多写几个下划线,例如函数名radix_tree_insert,因为它们在整个项目的许多源文件中都会用到,必须让使用者明确这个变量或函数是干什么用的。局部变量和只在一个源文件中调用的内部函数的命名可以简略一些,但不能太短,不要使用单个字母做变量名,只有一个例外:用i、j、k做循环变量是可以的。
-
针对中国程序员的一条特别规定:禁止用汉语拼音作为标识符名称,可读性极差。
-
函数
每个函数都应该设计得尽可能简单,简单的函数才容易维护。应遵循以下原则:
-
实现一个函数只是为了做好一件事情,不要把函数设计成用途广泛、面面俱到的,这样的函数肯定会超长,而且往往不可重用,维护困难。
-
函数内部的缩进层次不宜过多,一般以少于4层为宜。如果缩进层次太多就说明设计得太复杂了,应该考虑分割成更小的函数来调用(这称为HelperFunction)。
-
函数不要写得太长,建议在24行的标准终端上不超过两屏,太长会造成阅读困难,如果一个函数超过两屏就应该考虑分割函数了。Linux内核源代码的Documentation/CodingStyle文件中特别说明,如果一个函数在概念上是简单的,只是长度很长,这倒没关系。例如函数由一个大的switch组成,其中有非常多的case,这是可以的,因为各个case之间互不影响,整个函数的复杂度只等于其中一个case的复杂度,这种情况很常见,例如TCP协议的状态机实现。
-
执行函数就是执行一个动作,函数名通常应包含动词,例如get_current、radix_tree_insert。
-
比较重要的函数定义上面必须加注释,说此函数的功能、参数、返回值、错误码等。
-
另一种度量函数复杂度的办法是看有多少个局部变量,5到10个局部变量就已经很多了,局部变量再多就很难维护了,应该考虑分割函数。
分享到:
相关推荐
Linux kernel development 3rd edition, the classic good book
3882页Linux Kernel Documentation; Linux Kernel官方文档
linux kernel 中文版,本书是为那些想了解Linux 内核工作原理的Linux 狂热爱好者而写它并非一本内部 手册主要描叙了Linux设计的原理与机制以及Linux内核怎样工作及其原因 Linux还在不断改进本书基于目前比较流行且...
Linux Kernel Development中文第二版 第二部分,共两部分
Linux Kernel Development details the design and implementation of the Linux kernel, presenting the content in a manner that is beneficial to those writing and developing kernel code, as well as to ...
Linux Kernel Development.pdf Linux Kernel Development.pdf Linux Kernel Development.pdf
Linux Kernel中文版核心手册.rar
The Linux kernel is one of the most interesting yet least understood open-source projects. It is also a basis for developing new kernel code. That is why Sams is excited to bring you the latest Linux ...
Linux Kernel Programming Guide.pdf
Linux Kernel中文版核心手册.CHM
linux 设计原理和思路 很好的起步书籍
Linux Kernel in a Nutshell Linux Kernel in a Nutshell
The Linux Kernel Module Programming Guide 2.4 中文版
Professional Linux Kernel Architecture
Linux Kernel核心中文手册Linux Kernel核心中文手册Linux Kernel核心中文手册Linux Kernel核心中文手册Linux Kernel核心中文手册Linux Kernel核心中文手册
Understanding the Linux Kernel 3rd Edition (English Version)
Understanding The Linux Kernel 完美组合 Understanding The Linux Kernel 完美组合 Understanding The Linux Kernel 完美组合
Linux Kernel 四库全书,进阶学习Linux内核必备推荐书