程序设计实践笔记---风格

程序设计实践1-----风格

名字:

1 定义常数的时候,要用有意义的名字,他要能说明这些值在程序中所起的作用.

  不要这样: #define TWENTY 20

  而是: #define OUTPUT_BUFSIZE 20

2 全局变量使用具有说明性的名字,局部变量用短名字。根据定义,全局变量可以出现在整个程序中的任何地方,因此它们的名字应该足够长,具有足够的说明性,以便使读者能够记得它们是干什么用的。给每个全局变量声明附一个简短注释也非常有帮助. 全局函数、类和结构也都应该有说明性的名字,以表明它们在程序里扮演的角色

3 命名保持一致性, 名字要准确,他不仅是个标记,还携带着给读程序人的信息,误用的名字可能引起奇怪的程序错误.

4 对返回布尔类型值(真或者假)的函数命名,应该清楚地反映其返回值情况.      isoctal() 当是八进制数值时返回真.

5 函数应采用动作性的名字.

6 按常规方式使用的局部变量可以采用极短的名字。例如用ij作为循环变量,pq作为指针,st表示字符串等。这些东西使用得如此普遍,采用更长的名字不会有什么益处或收获,可能反而有害.

 

表达式与语句

1 名字的合理选择可以帮助读者理解程序,同样,我们也应该以尽可能一目了然的形式写好表达式和语句。应该写最清晰的代码,通过给运算符两边加空格的方式说明分组情况,更一般的是通过格式化的方式来帮助阅读。这些都是很琐碎的事情,但却又是非常有价值的,就像保持书桌整洁能使你容易找到东西一样。与你的书桌不同的是,你的程序代码很可能还会被别人使用

2 用缩行显示程序的结构。采用一种一致的缩行风格,是使程序呈现出结构清晰的最省力的方法

3 用加括号的方式排除二义性括号表示分组,即使有时并不必要,加了括号也可能把意图表示得更清楚。在上面的例子里,内层括号就不是必需的,但加上它们没有坏处。熟练的程序员会忽略它们,因为关系运算符(< <= == != >= )> 逻辑运算符(& &| |)的优先级更高。在混合使用互相无关的运算符时,多写几个括号是个好主意。C语言以及与之相关的语言存在很险恶的优先级问题,在这里很容易犯错误.

4 分解复杂的表达式CC + +J a v a语言都有很丰富的表达式语法结构和很丰富的运算符。

5 要清晰。程序员有时把自己无穷尽的创造力用到了写最简短的代码上,或者用在寻求得到结果的最巧妙方法上。有时这种技能是用错了地方,因为我们的目标应该是写出最清晰的代码,而不是最巧妙的代码.

6 当心副作用。像++ 这一类运算符具有副作用,它们除了返回一个值外,还将隐含地改变变量的值。副作用有时用起来很方便,但有时也会成为问题,因为变量的取值操作和更新操作可能不是同时发生。CC++ 对与副作用有关的执行顺序并没有明确定义,因此下面的多次赋值语句很可能将产生错误结果:

str[i++] = str[i++] = ‘’;

 

一致性和惯用法:

1 使用一致的缩排和加括号风格。缩排可以显示出程序的结构,那么什么样的缩排风格最好呢?是把花括号放在i f的同一行,还是放在下面一行?程序员们常常就程序的这些编排形式争论不休。实际上,特定风格远没有一致地使用它们重要。不要在这里浪费时间.

 

函数宏:

1 避免函数宏。C++ 里,在线函数更削减了函数宏的用武之地,在J a v a里根本就没有宏这种东西。即使是在C语言里,它们带来的麻烦也比解决的问题更多。

2 给宏的体和参数都加上括号。如果你真的要使用函数宏,那么请特别小心。宏是通过文本替换方式实现的:定义体里的参数被调用的实际参数替换,得到的结果再作为文本去替换原来的调用段。

3 C ++ 提供的在线函数既避免了语法方面的麻烦,而且又可得到宏能够提供的执行效率,很适合用来定义那些设置或者提取一个值的短小函数。

4 函数宏最常见的一个严重问题是:如果一个参数在定义中出现多次,它就可能被多次求值。如果调用时的实际参数带有副作用,结果就会产生一个难以捉摸的错误

 #define MAX(x, y) ((x) > (y)? (x) : (y))

 MAX(i++, j);

 

神秘的数:

神秘的数包括各种常数、数组的大小、字符位置、变换因子以及程序中出现的其他以文字形式写出的数值

1 给神秘的数起个有意义的名字。作为一个指导原则,除了01之外,程序里出现的任何数大概都可以算是神秘的数,它们应该有自己的名字。在程序源代码里,一个具有原本形式的数对其本身的重要性或作用没提供任何指示性信息,它们也导致程序难以理解和修改。

 

2 把数定义为常数,不要定义为宏C程序员的传统方式是用# d e f i n e行来对付神秘的数值。C语言预处理程序是一个强有力的工具,但是它又有些鲁莽。使用宏进行编程是一种很危险的方式,因为宏会在背地里改变程序的词法结构。我们应该让语言去做正确的工作。在CC++ 里,整数常数可以用枚举语句声明,就像上面的例子里所做的那样。在C + +里任何类型都可使用const声明的常数:

const int MAXROW = 24.

C语言里也有const值,但它们不能用作数组的界。这样, e n u m就是C中惟一可用的选择了.

3 与此类似的还有另一个问题,那就是程序里许多上下文中经常出现的0。虽然编译系统会把它转换为适当类型,但是,如果我们把每个0的类型写得更明确更清楚,对读程序的人理解其作用是很有帮助的。例如,用(v o i d *) 0null表示C里的空指针值,用‘/ 0’ 而不是0表示字符串结尾的空字节,不要写成:

4 利用语言去计算对象的大小。不要对任何数据类型使用显式写出来的大小。例如,我们应该用s i z e o f (i n t) 而不是2或者4。基于同样原因,写s i z e o f ( a r r a y [ 0 ] ) 可能比s i z e o f(i n t) 更好,因为即使是数组的类型改变了,也没有什么东西需要改变.

5 CC + +里没有直接求数组大小的函数。但是,对于那些可以看清楚的数组(不是指针)下面的宏定义能计算出数组的元素个数

       #define NELEMS(array) sizeof(array) / sizeof(array[0])

   在这里,数组大小只在一个地方设置。如果数组的大小改变,其余代码都不必改动。对函数参数的多次求值在这里也不会出问题,因为它不会出现任何副作用,事实上,这个计算在程序编译时就已经做完了。这是宏的一个恰当使用,因为它做了某种函数无法完成的工作,从数组声明计算出它的大小。

 

注释:

1 注释应该提供那些不能一下子从代码中看到的东西,或者把那些散布在许多代码里的信息收集到一起。当某些难以捉摸的事情出现时,注释可以帮助澄清情况。如果操作本身非常明了,重复谈论它们就是画蛇添足了.

2 给函数和全局数据加注释。注释当然可以有价值。对于函数、全局变量、常数们都应该为之提供注释。全局变量常被分散使用在整个程序中的各个地方,写一个注释可以帮人记住它的意义,也可以作为参考

3 有些代码原本非常复杂,可能是因为算法本身很复杂,或者是因为数据结构非常复杂。在这些情况下,用一段注释指明有关文献对读者也很有帮助。此外,说明做出某种决定的理由也很有价值.

4 不要注释差的代码,重写它。应该注释所有不寻常的或者可能迷惑人的内容。但是如果注释的长度超过了代码本身,可能就说明这个代码应该修改了

5 不要与代码矛盾。许多注释在写的时候与代码是一致的。但是后来由于修正错误,程序改变了,可是注释常常还保持着原来的样子,从而导致注释与代码的脱节。这很可能是本章开始的那个例子的合理解释。

无论产生脱节的原因何在,注释与代码矛盾总会使人感到困惑。由于误把错误注释当真,常常使许多实际查错工作耽误了大量时间。所以,当你改变代码时,一定要注意保证其中的注释是准确的。

6 学生常被告之应该注释所有的内容。职业程序员也常被要求注释他们的所有代码。但是,应该看到,盲目遵守这些规则的结果却可能是丢掉了注释的真谛。注释是一种工具,它的作用就是帮助读者理解程序中的某些部分,而这些部分的意义不容易通过代码本身直接看到。我们应该尽可能地把代码写得容易理解。在这方面你做得越好,需要写的注释就越少。好的代码需要的注释远远少于差的代码。

 

 

 

 

 

 

 

你可能感兴趣的:(数据结构,C++,c,工作,语言,工具)