《代码大全2》阅读笔记07Chapter 12 Fundamental Data Types

Chapter 12 Fundamental Data Types
 基本数据类型

基本数据类型是构建其他所有数据类型的构造块(building blocks)。
12.1 Number In General 数值概论
1. 避免使用“神秘数值” (magic number)
 神秘数值是在程序中出现的,没有经过解释的数值文字量(litertal numbers),如100,47,523.
2. 如果需要,可以使用硬编码的0和1
 数值0和1用于增量,减量和从数组的第一个元素开始循环。
3. 预防除零(devide-by-zero)错误
4. 使类型转换变得明显
5. 避免混合类型的比较
6. 注意编译器的警告。
 杰出的程序员会修改他们的代码来消除所有的编译器警告。通过编译器警告来发现问题要比你自己找容易的多。

12.2 Integers 整数
1. 检查整数除法
2. 检查整数溢出
 避免整数溢出的最简单办法是考虑清楚算术表达式中的每个项,设想每项可能达到的最大值。
3. 检查中间结果溢出

12.3 Floating-Point Numbers 浮点数
 很多10进制小数不能够精确地用数字计算机中的1和0来表示。像1/3或者1/7这样的无限循环小数通常只用7位或者15

位精度有效数字表示。例如MS VB中,1/3的32位浮点数表示为0.33 333 330。它的精度是小数点后7位。
下面是一些浮点数使用时,应该遵循的指导原则:
1. 避免数量级相差巨大的数之间的加减运算。
 32位浮点变量,1000000.00 + 0.1可能会得到1000000.00,因为32位不能给你足够的有效位数包容1000000和0.1

之间的数值区间。与之类似,5000000.02-5000000.01很可能会得到0.0。
 解决方案是,如果你必须把一系列差异如此巨大的数相加,那么就先对这些数排序,然后从最小值开始把它们加起来。

——本质上来说,是要做逆向的求和运算。
2. 避免等量判断
 很多应该相等的浮点数值并不一定相等。用两种不同的方法来求同一数值,结果不一定总得到同一个值。
 当比较时,应该找一种代替对浮点数执行等量判断的方案。一种有效的方法:先确定可接受的精度范围,然后用布尔函

数判断数值是否足够接近。
3. 处理舍入误差问题
4. 检查语言和函数库对特定数据类型的支持

12.4 Characters and Strings 字符和字符串
1. 避免使用神秘字符和神秘字符串 (magic character and magic string)
 如果编程语言是支持具名变量,则用具名变量加以取代。否则使用全局变量。
2. 避免off-by-one错误
 由于子字符串的下标索引方式几乎和数组相同,因此要避免因为读写操作超出了字符串末尾’而导致的off-by-one(偏差

一)错误。
3. 了解你的语言和开发环境是如何支持Unicode的。
 Java中所有字符串都是Unicode的。在C和C++等其他语言里,处理Unicode就要用到与之相关的一组函数。所以要尽

早决定是否采用Unicode字符集。如果你决定要用Unicode字符串,就要决定何处以及何时使用它。
4. 在程序生命周期中尽量早决定国际化/本地化策略。
5. 如果你知道只需要支持一种文字的语言,请考虑使用ISO8859字符集
  对于只需要支持但以文字(例如英语),无须支持多语言或者某种表意语言(例如汉语)的应用程序,可以使用

ISO8859扩展ASCII类型标准来很好的代替Unicode。
6. 如果需要支持多语言,请使用Unicode。
7. 采用某种一致的字符串类型转换策略。

·C语言中的字符串 Strings in C
 1. 注意字符串指针和字符数组之间的差异
 警惕任何包含字符串何等号的表达式
 在C里面,StringPtr=“some text”; 这种情况下,“some text”是一个指向字面量字符串的指针,因此这个赋值结果

只是让StringPtr指针指向该字面字符串。这个赋值并没有把字符串内容拷贝到StringPtr。
 通过命名规则区分变量是字符数组还是字符串指针。
 把C-style字符串的长度声明为CONSTANT+1
 用null初始化字符串以避免没有终端的字符串。
 用字符数组取代C中的指针
 用strncpy()取代strcpy()以避免无终端的字符串

12.5 布尔变量 Boolean Variables
1. 用布尔变量对程序加以文档说明。
 不同于仅仅判断一个布尔表达式,你可以把这种表达式的结果赋给一个变量,从而使得这一判断的含义变得明显。例如


 if((elementIndex<0) || (MAX_ELEMENTS < elementIndex) || (elementIndex == lastElementIndex) )
 {....}
 下面的代码中,布尔变量的使用使得if的判断对象明确很多。
 finished = ((elementIndex<0) || (MAX_ELEMENTS < elementIndex) );
 repeatedEntry = (elementIndex == lastElementIndex);
 if(finished || repeatedEntry)
 {...}

2. 布尔变量来简化复杂的判断
 例子如上。
3. 如果需要的话,创建你自己的布尔类型。

12.6 枚举类型 Enumerated Types
1. 用枚举类型来提高可读性
2. 用枚举类型来提高可靠性
3. 用枚举类型来简化修改
4. 将枚举类型作为布尔变量的替换方案
5. 检查非法数值
6. 定义出枚举的第一项和最后一项,以便用于循环边界
 例如在VB中,
 Public Enum Country
  Country_First = 0
  Country_China = 0
  Country_England = 1
  Country_France = 2
  Country_USA = 6
  Country_Last = 6
 End Enum
 然后就可以把Country_First和Country_Last用做循环边界了:
 For iCountry = Country_First To Country_Last
  ...
 Next
7. 把枚举类型的第一个元素留做非法值。
8. 明确定义项目代码编写标准中第一个和最后一个元素的使用规则,并且在使用时保持一致。
9. 警惕给枚举元素明确赋值而带来的失误。

·如果你的语言里没有枚举类型 If your language Doesn't Have Enumerated Types
如果没有枚举类型,那么可以用全局变量或者类来模拟它。例如Java中,(也许Java现在已经支持枚举类型了)
 Class Country{
  private Country() {}
  public static final Country China = new Country();
  public static final Country England = new Country();
  public static final Country France = new Country();
  。。。。。。
  public static final Country USA = new Country();
 }

12.7 具名常量 Named Constants
1. 在数据声明中使用具名常量
 例如 Const LOCAL_NUMBER_LEGHTH = 7
2. 避免使用文字量,即使是“安全”的
3. 用具有适当作用域的变量或类来模拟具名常量(如果语言不支持的话)
4. 统一的使用具名常量

12.8 数组 Arrays
1. 确认所有的数组下标都没有超出数组的边界
2. 考虑用容器来取代数组,或者将数组作为顺序化结构来处理
 计算机科学界的一些聪明的人士建议永远不要随机地访问数组,只能顺序地访问(Mills and Linger 1986)。他们的

论点是,在数组中随机访问就像在程序中随便使用Goto语句一样。他们建议使用集合,栈和队列等按顺序存取元素的数据结构来取

代数组。
 在你习惯性地选用数组之前,考虑能否用其他可以顺序访问数据的容器类作为替换方案——如集合,栈,队列等等。
3. 检查数组的边界点
4. 如果数组十多维的,确认下标的使用顺序是正确的。
5. 提防下标串话
 如果你在使用嵌套循环,那么会很容易把Array[i]写成Array[j]。调换循环下标称为“下标串话cross-talk”。应该使用比

i和j更有意义的下标名,从而降低下标串话错误的发生。
6. 在C中结合ARRAY_LENGTH()宏来使用数组。

12.9 创建自己的类型(类型别名) Creating Your Own Types(Type Aliasing)
创建自己的类型的原因
1. 易于修改
2. 避免过多的信息发布
3. 增加可靠性
4. 弥补语言的不足
·创建自定义数据类型的知道原则 Guidelines for Creating Your Own Types
1. 该所创建的类型取功能导向的名字
2. 避免使用预定义类型
3. 不要重定义一个预定义的类型
4. 定义替代类型以便于移植
5. 考虑创建一个类而不是使用typedef。

Key Points
1. 使用特定的数据类型就意味着要记住适用于各个类型的很多独立的原则。
2. 如果你的语言支持,创建自定义类型会使得你的程序更容易修改,并更具有自描述性。
3. 当你用typedef或者其等价方式创建了一个简单类型的时候,考虑是否应该创建一个新的类。

Desire has no rest.
原文地址:https://www.cnblogs.com/samcn/p/1449910.html