Chinaunix首页 | 论坛 | 博客
  • 博客访问: 210434
  • 博文数量: 58
  • 博客积分: 2807
  • 博客等级: 少校
  • 技术积分: 610
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-09 14:18
文章分类

全部博文(58)

文章存档

2012年(1)

2011年(17)

2010年(40)

我的朋友

分类: C/C++

2010-10-13 00:44:25

Programs must be written for people to read, and only incidentally for machines to execute.”代码主要是为了写给人看的,而不是写给机器看的,只是顺便也能用机器执行而已。代码和语言文字一样是为了表达思想、记载信息,所以一定要写得清楚整洁才能有效地表达。正因为如此,在一个软件项目中,代码风格一般都用文档规定死了,所有参与项目的人不都要遵守统一的风格,例如Linux内核[CodingStyle]就是这样一个文档。本章我们以内核的代码风格为基础来讲解好的编码风格都有哪些规定,这些规定的Rationale是什么。我只是以Linux内核为例来讲解编码风格的概念,并没有说内核编码风格就一定是最好的编码风格,但Linux内核项目如此成功,就足以说明它的编码风格是最好的C语言编码风格之一了。

UNIX系统标准的字符终端是24行80列

1. 缩进和空白 

我们知道C语言的语法对缩进和空白没有要求,空格、Tab、换行都可以随意写,实现同样功能的代码可以写得很好看,也可以写得很难看。[CodingStyle]中关于空白字符并没有特别规定,因为基本上所有的C代码风格对于空白字符的规定都差不多,主要有以下几条。

1、关键字ifwhilefor与其后的控制表达式的(括号之间插入一个空格分隔,但括号内的表达式应紧贴括号。例如:

while␣(1);

2、双目运算符的两侧各插入一个空格分隔,单目运算符和操作数之间不加空格,例如i␣=␣i␣+␣1++i!(i␣<␣1)-x&a[1]等。

3、后缀运算符和操作数之间也不加空格,例如取结构体成员s.a、函数调用foo(arg1)、取数组成员a[i]

4、,号和;号之后要加空格,这是英文的书写习惯,例如for␣(i␣=␣1;␣i␣<␣10;␣i++)foo(arg1,␣arg2)

5、以上关于双目运算符和后缀运算符的规则并没有严格要求,有时候为了突出优先级也可以写得更紧凑一些,例如for␣(i=1;␣i<10;␣i++)distance␣=␣sqrt(x*x␣+␣y*y)等。但是省略的空格一定不要误导了读代码的人,例如a||b␣&&␣c很容易让人理解成错误的优先级。

6、由于UNIX系统标准的字符终端是24行80列的,接近或大于80个字符的较长语句要折行写,折行后用空格和上面的表达式或参数对齐,例如:

if␣(sqrt(x*x␣+␣y*y)␣>␣5.0
    &&␣x␣<␣0.0
    &&␣y␣>␣0.0)

再比如:

foo(sqrt(x*x␣+␣y*y),
    a[i-1]␣+␣b[i-1]␣+␣c[i-1])

7、较长的字符串可以断成多个字符串然后分行书写,例如:

printf("This is such a long sentence that "
       "it cannot be held within a line\n");

C编译器会自动把相邻的多个字符串接在一起,以上两个字符串相当于一个字符串"This is such a long sentence that it cannot be held within a line\n"

8、有的人喜欢在变量定义语句中用Tab字符,使变量名对齐,这样看起来很美观。

       →int    →a, b;
       →double →c;

内核代码风格关于缩进的规则有以下几条。

1、要用缩进体现出语句块的层次关系,使用Tab字符缩进,不能用空格代替Tab。在标准的字符终端上一个Tab看起来是8个空格的宽度,如果你的文本编辑器可以设置Tab的显示宽度是几个空格,建议也设成8,这样大的缩进使代码看起来非常清晰。如果有的行用空格做缩进,有的行用Tab做缩进,甚至空格和Tab混用,那么一旦改变了文本编辑器的Tab显示宽度就会看起来非常混乱,所以内核代码风格规定只能用Tab做缩进,不能用空格代替Tab。

2、if/elsewhiledo/whileforswitch这些可以带语句块的语句,语句块的{或}应该和关键字写在同一行,用空格隔开,而不是单独占一行。例如应该这样写:

if␣(...)␣{
       →语句列表
}␣else␣if␣(...)␣{
       →语句列表
}

但很多人习惯这样写:

if␣(...)
{
       →语句列表
}
else␣if␣(...)
{
       →语句列表
}

内核的写法和一致,好处是不必占太多行,使得一屏能显示更多代码。这两种写法用得都很广泛,只要在同一个项目中能保持统一就可以了。

3、函数定义的{和}单独占一行,这一点和语句块的规定不同,例如:

int␣foo(int␣a,␣int␣b)
{
       →语句列表
}

4、switch和语句块里的casedefault对齐写,也就是说语句块里的casedefault标号相对于switch不往里缩进,但标号下的语句要往里缩进。例如:

      →switch␣(c)␣{
      →case 'A':
      →       →语句列表
      →case 'B':
      →       →语句列表
      →default:
      →       →语句列表
      →}

用于goto语句的自定义标号应该顶头写不缩进,而不管标号下的语句缩进到第几层。

5、代码中每个逻辑段落之间应该用一个空行分隔开。例如每个函数定义之间应该插入一个空行,头文件、全局变量定义和函数定义之间也应该插入空行,例如:

#include 
#include 

int g;
double h;

int foo(void)
{
       →语句列表
}

int bar(int a)
{
       →语句列表
}

int main(void)
{
       →语句列表
}

6、一个函数的语句列表如果很长,也可以根据相关性分成若干组,用空行分隔。这条规定不是严格要求,通常把变量定义组成一组,后面加空行,return语句之前加空行,例如:

int main(void)
{
       →int    →a, b;
       →double →c;

       →语句组1

       →语句组2

       →return 0;
}
阅读(770) | 评论(0) | 转发(0) |
0

上一篇:list.h container_of

下一篇:DokuWiki

给主人留下些什么吧!~~