资料收集站

SDL

Monday
Jan 05th
Text size
  • Increase font size
  • Default font size
  • Decrease font size

C代码风格

人们看到的最好的作家有时并不理会修饰学的规则。
还好,当他们这样做虽然付出了违反常规的代价,
读者还经常能从句子中发现某些具有补偿性的价值,
除非作者也明确其做法的意思,否则最好还是按规矩做

——William Strunk AND E.B White 《风格的要素》


作者:丁春秋
(如果您要转载这篇文章,请不要删减里面任何内容,珍惜劳动者的成果)

这是我的第一篇技术贴,也是我对代码风格的一点想法。一点点感悟
如果我的认识有错误,还请大家不吝赐教。

我们(C程序员,渴望成为C程序员的人)全为着一个共同的目标
而前进——钻研C语言的最深魅力。
我们感谢得C语言的缔造者Dennis M.Ritchie让我们可以使用这样
一个神奇的语言。他是所有C程序员心中的圣人。

我常被问及C语言的各种问题,但是很少人跟我讨论过代码风格。
一次我不经意的问一个硕士生,他的回答让我汗颜。
ME:“你的代码风格不是太好。”
HE:“那你说说我的代码风格是怎么个不好?”
ME:“……”
HE:“代码最重要的是性能,风格是其次”

最后一句话让我最起码沉默了十分钟。试问,没有风格哪来性能?
好的风格对于好的程序具有关键性的作用;
请你给下面两个程序代码捉虫。

/******例程1********/

#include
int main()
{int Number[10],Numadd_One,l,Numadd_Tow;
for(Numadd_One=0;Numadd_One<10;Numadd_One++)
scanf("%d",&Number[Numadd_One]);
for(Numadd_One=0;Numadd_One<10;Numadd_One++)
for(Numadd_Tow=0;Numadd_Tow<10;Numadd_Tow++)
{if(Number[Numadd_Tow]>Number[Numadd_Tow+1]){
l=Number[Numadd_Tow];Number[Numadd_Tow] =
Number[Numadd_Tow+1];Number[Numadd_Tow+1]=j;}
}
}


/*******例程2*******/

#include

#define MAX 10

int main()
{
int number[MAX];
int n;
int j;
int temp;

for( n = 0 ; n < MAX ; n++ )
scanf( "%d",&number[n] );

for( n = 0 ; n < MAX ; n++ ){
for( j = 0 ; j < MAX ; j++ ){
if( number[j] > number[j + 1] ){
temp = number[j];
number[l] = number[j + 1];
number[j + 1] = temp;
}
}
}
}


在这里,有着代码风格的代码好处就明显现露出来了。别告诉
我你觉得第一个例子的风格够好……
代码应该是清楚的简单的具有直截了当的逻辑,自然的表达式。
而不是一篇乱七八糟的作文稿。

对,没错,第一个例子的变量申明确可以省下不少时间和占用
空间,但是你忘记刚才捉虫的经历了吗?如此的代码格式会让你
的同事抓狂。
int PlaseInput,NumberIput,l,KillerNumber;
在中间的l不经意就会没看见它;
如果分开写的话会让你和你的同事看的更清楚,对变量名称更了解;


Number[10],Numadd_One,Numadd_Tow……
等等,这样的变量名字看起来实在是太罗嗦。
名字是什么?一个名字是用来标识函数或变量的对象。
要带着一些有用途的信息,一个名字应该是非形式的,简单的,
容易记的。一个变量的作用越大,它名字要携带的信息就该更多。
全局变量应该更加注意些。
作为非明文规定,局部变量应用小写字母,
全局变量应大写开头字母;
常量名应全大写;
函数名应该写为动作性的;
结构名应该带有整体性;
有很多人总是鼓励变量名写的够长,容易携带信息;
那是鬼话,清晰都是随着简洁而来的。

表达式的缩进状态是非常重要的,把刚才的例程1和例程2对比一下
就有明显的结果。表达式的缩进效果应该可以你可以瞬间毫不费力的
看完而不会觉得象一块压缩饼干一样积压在一起。而且还要求可以
看到相当清晰的结构性,没有一点视觉上的障碍。
表达式应该有够自然,应该可以让你大声的读出来。

如果遇到了优先级的判断时,并不确定哪个先执行或哪个后执行时
加上括号强调她的优先级,这没有错,也并不羞耻。不要害怕谁说
你连优先级都没背清楚……

有时候我们尽力把创造力发挥在简短的代码上,从而寻求最简短的
解决办法,但是有时候这技巧用错了地方,我们写代码的目的是写出
清晰易懂的代码,而不是炫耀自己的创造力。

看看这代码到底想要做些什么

subkey = subkey >> (bitoff - ( (bitoff >> 3) << 3 ));

记住,清晰性并不等于简短,这里是互相矛盾的。
有时候短的代码更容易说明一切,也有时候短的代码也搞混一切。

可怕的魔术数字

什么是可怕的魔术数字?
看下列代码

for( i = 3 ; i + 3 / 4 ? i++ : i-- ; n++ , p++ ){
if( p < 200 )
p = p / 3 - i / 5;
}

这个循环代码实在是有够可怕的,但是可怕的并不是这个循环。
而是这里面的数字,她们在不停的变化。这不是最糟糕的;
糟糕的是你将在30000行的程序中更改这些数字……

但是假如你先知性的做了准备将这些幻数定义为常量或枚举,
那你的情况就不会这么糟糕了。

也有人说把数字定义为常数而不是宏,这是有弊有利的。
大家自己权衡情况。

你写过注释吗?你为自己程序做过文档吗?

注释是自己程序的好向导,文档是自己的好帮手。
不要以为程序是自己写的不可能忘记,那你就大错他错了。
我记得我做新手的时候开发项目,是老手带领我们几个新手来做。
我负责的那部分模块相当简单,我很快就草草了事了。
然后也没管太多,谁知道程序演示版被客户返工了。
我和另外两个兄弟负责的模块有问题,但离交工的日子不远了,
我和另外两个兄弟连夜赶工,但是我发现我自己写的代码竟然有好多
功能连我自己都不清楚了。我当时真恨我注释和文档没写清楚。
要不然就没有那么尴尬的情况出现了。后来把这个模块重新写了一遍
调了N遍,那最后一天终于通过客户那一关了。
整个人累的跟只死狗一样。

无论是新手还是老手,都应该写好注释和文档,
必要的时候文档应当记录实现某些功能的代码方案,
写注释的风格有N多种,我这里就不说了。
总之找到一种适合自己的风格,然后坚持下去。
让这种风格成为习惯,但是这风格一定要让其他人接受。
尽量和其他人保持风格的一致性,你看别人的代码轻松。
别人看你的代码也同样轻松。

另外如何鉴定自己的风格?

如果你找到一种自己喜欢的风格,不要问,使用她吧。等你按照这种风格写过
100行的程序之后,叫来几个懂计算机语言的朋友,让她们来感觉这些英文代码
和你以前写的是否看起来更舒服。

最后请记住,一个风格好的程序比那些风格差的程序更容易读,也更容易修改。


Comments (0)Add Comment

Write comment

busy
 

Google 搜索

在线用户

We have 121 guests online