*可以少犯错误的使用数的建议
#避免使用“神秘数值(magicnumber)”
神秘数值时在程序中出现的并且没有经过解释的数值文字量。
如果你使用的编程语言支持具名常量,那么就用它来代替神秘数值,如果你无法使用具名常量,在可行的情况下应该使用全局变量。
避免使用神秘数值,可以增强代码的可读性,并且使修改变得更容易,更可靠。
#如果需要,可以使用硬编码的0和1
数值0和1用于增量,减量和从数组的第一个元素开始循环。
一条很好的经验法则是,程序主体中仅能出现的文字量就是0和1,任何其他文字量都应该换成更有描述性的表示。
#预防除零(devide-by-zero)错误
每次使用除法符号的时候,都要考虑表达式的分母是否可能为0。
#使类型转换变得明显
因为隐式的类型转换在不同的编译器会执行不同的转换,为了避免这种不确定性,请明确告知编译器你需要的转换。
C++代码:y=x+(float)i;
VB代码:y=x+CSng(i);
#避免混合类型的比较
当要做比较测试的两个数值的类型不同时,请动手进行类型转换,这样编译器就会把代码编译成你期望的结果。
#注意编译器的警告
通过编译器警告来发现问题要比自己找容易得多。
*使用整数时的注意事项
#检查整数除法
整数除法的结果还是整数,所以当你执行10*(7/10)的计算时,其结果是0,而不是你所期待的结果。对此问题最简单的补救方法就是重新安排表达式的顺序。如安排成:(10*7)/10,结果就准确了。
#检查整数溢出
在做整数的乘法或者加法时,要注意可能的最大整数。
要检查算术表达式的每一项,使用最合理的类型来避免整数的溢出。
#检查中间结果的溢出
如果在计算某一项时,中间结果也可能溢出,那么请换用一种更长的整形或者浮点类型。
*使用浮点数时的注意事项
#避免数量级相差巨大的数之间的加减运算
使用数量级相差巨大的数进行加减运算时,有可能不能得到你希望的结果,如果不可避免要使用这种运算,就先对这些数进行排序,然后从最小值开始把它们加起来,这样做虽然不能消除舍入问题,但是能使这一问题的影响减少到最低限度。
#避免等量判断
很多应该相等的浮点数值并不一定相等。这里的根本问题是,用两种不同的方法来求同一数值,结果不一定总得到同一个值。
因此应该找一种替代方案,一种有效的方法是先确定可接受的精度范围,然后用布尔函数判断数值是否足够接近。
#处理舍入误差问题
这里有处理舍入误差的常见方案
&换一种精度更高的变量类型
&换用二进制编码的十进制变量,即BCD模式。
&把浮点变量变成整型变量。采用这种方法,需要自己处理数字的小数部分。
如果语言中有内置的处理敏感数值的类型,如VB种的Currency等等,就使用它。
*使用字符串的技巧
#避免使用神秘字符和神秘字符串
同神秘数值一样,神秘字符和字符串也是不应该有的,如果你用的编程语言支持具名常量,则用具名常量来加以取代。否则就用全局变量。
#避免off-by-one错误
由于子字符串的小标索引方式几乎与数组相同,因此要避免因为读写操作超出了字符串末尾而导致的off-by-one错误。
#了解你的语言和开发环境是如何支持Unicode的
为了标准函数库与第三方函数库之间的通信,常常需要在Unicode和其他字符集之间进行转换。如果有些字符串不需要表示成Unicode,就要尽早决定是否采用Unicode字符集。如果你决定要用Unicode字符串,就要决定何处以及何时使用它。
#在程序生命周期中尽早决定国际化/本地化策略
与国际化和本地化相关的事项都是很重要的问题,要尽早决定。
#如果你知道只需要支持一种文字的语言,请考虑使用ISO8859字符集
#如果你需要支持多种语言,请使用Unicode
#采用某种一致的字符串类型转换策略
如果你使用了多种字符串类型,有一种常用的方法能维护各种字符串类型,那就是在程序中把所有字符串都保存为一种格式,同时在尽可能靠近输入和输出操作的位置把字符串转换为其他格式。
*布尔变量的使用技巧
#用布尔变量对程序加以文档说明
不同于仅仅判断一个布尔表达式,你可以把这种表达式的结果赋给一个变量,从而使得这一判断的含义变得明显。
#用布尔变量来简化复杂的判断
当判断十分复杂的时候,使用布尔变量来标注,将十分有效,增强代码的可读性。
#如果需要的话创建自己的布尔类型
有些语言,比如C++,Java和VB,含有预定义的布尔类型,而其他语言,比如C,则没有,在没有布尔类型的语言中定义自己的布尔类型。
如C中的定义:
EnumBoolean{
TRUE=1,
FALSE=(!TRUE)
};
*枚举类型的使用技巧
#用枚举类型来提高可读性
#用枚举类型来提高可靠性
#用枚举类型来简化修改
#将枚举类型作为布尔变量的替换方案
#检查非法数值
#定义出枚举的第一项和最后一项,以便用于循环边界
#把枚举类型的第一个元素留作非法值
#明确定义项目代码编写标准中第一个和最有一个元素的使用规则,并且在使用时保持一致
#警惕给枚举元素明确赋值而带来的失误
如果使用的编程语言中没有枚举类型,那么可以使用全局变量或者类来模拟它。
*具名常量的使用
具名常量很像变量,一旦赋值以后就不能再修改了。具名常量允许你用一个名字而不是数字来表示固定的量。
#在数据声明中使用具名常量
在需要定义所用数据的大小的数据声明和其他语句里,使用具名常量可以提高程序的可读性和可维护性。
#避免使用文字量,即使是“安全”的
#用具有适当作用域的变量或类来模拟具名常量
#统一地使用具名常量
如果需要表示的是同一个实体,在一处使用具名常量,而在另一处使用数字符号是非常危险的。这样的编程实践就是在自找麻烦。请统一使用具名常量。
*数组的使用
#确认所有的数组下标都没有超出数组的边界
#考虑用容器来取代数组,或者将数组作为顺序化结构来处理
#检查数组的边界点
#如果数组是多维的,确认下标的使用顺序是正确的
很容易把array[i][j]写成array[j][i],所以请花点时间检查下标的顺序是否正确。与其用i和j这类不明不白的东西,不如去考虑更有意义的名字。
#提防下标串话
如果你在使用嵌套循环,那么很容易把array[i]写成array[j],请检查这种问题。更好的做法是使用比i和j更具有意义的下标名。
#在C中结合ARRAY_LENGTH()宏来使用数组
定义:#defineARRAY_LENGTH(x)(sizeof(x)/sizeof(x[0]))
在使用时,用ARRAY_LENGTH()宏取代具名常量来表示数组大小的上限。
*创建自定义数据类型的指导原则
#给所创建的类型取功能导向的名字
#避免使用预定义类型
#不要重定义一个预定义的类型
#定义替代类型以便于移植
#考虑创建一个类而不是使用typedef
要点
@使用特定的数据类型就意味着要记住适用于各个类型的很多独立的原则。
@如果你的语言支持,创建自定义类型会使得你的程序更容易修改,并更具有自描述性。
@当你用typedef或者其等价方式创建了一个简单类型的时候,考虑是否更应该创建一个新的类。
参考:
《代码大全》第二版,第十二章,基本数据类型