5.1 避免非平凡的指针算术。
复杂的指针算术通常不必要,最好避免。原因是可能导致未定义的结果。两个指针指向同一个数组的元素时,指针相减才有意义。指针加上或者减去一个整数,得到的结果还是一个指针,如果这个值不指向原来指针指向的数组的元素,那么使用这个值得结果就是无定义的。指针相加没有意义,因此不被允许。
5.2 当心,不要超出数组的界线去写。
使用数组时总是应该对数组越界保持警觉。一旦数组越界,就会产生无定义的结果,程序可能会崩溃或者稀里糊涂的继续运行。缓冲区溢出是黑客广泛利用的一种攻击手段,它就是利用超出数组的界线去写内存来达到目的的,所以我们应使用带有长度检查的函数版本,如strncpy, snprintf等等, 而不是strcpy, sprintf。
2.3 尽量使用0而不是NULL。
对于0和NULL的是非曲直, imperfect C++中有详细的介绍,我们应该记住C++中使用0而不是NULL。
5.4 尽量使用vector和valarray而不是内部的数组。
vector被设计用来模拟动态数组,它的内存布局和C数组时一样的。这里有一个用vector代替C数组的例子。
std::vector<char> v; // create vector as dynamic array of chars
v.resize(41); // make room for 41 characters (including '/0')
strcpy(&v[0], "hello, world"); // copy a C-string into the vector
printf("%s/n", &v[0]); // print contents of the vector as C-string
5.5 尽量使用string而不是以0结尾的char数组。
C风格char数组依靠0来确定字符个数,标准库的string存有长度,并不依赖于0来确定大小。而且string中还可以包含0,需要注意的是如果string表示的字符串中间含有0,这时调用c_str()返回一个const char* 指针, 如果用strlen来对这个值这求长度, 那么这个长度是不正确的, 他并不等于string的成员函数length()返回的值。Effective STL中条款13更详细的解释了使用string代替以0结尾的char数组
5.6 尽量少用普通的引用参数。
普通的引用参数如 void f(int& i),调用时是f(x),这种形式并不能给人x的值被修改的提示信息,而x=f(x)或者f(&x)则可以。所以应少用普通的引用参数。但在实际中用普通的引用参数作为输出参数是很常见的,这时可以用有提示意义的函数名,如update(x)。
5.7 避免void*,除了在某些低级代码里。
void*常常出现在系统中很低的层次,如果在系统较高层次上出现void*,应该认为是可疑的, 就像设计错误的指示器。值得注意的是,到函数的指针和到成员的指针都不能赋给
void*。
5.8 避免在代码里使用非平凡的文字量(神秘的数)。相反,应该定义和使用各种符号常量。
避免在代码里使用非平凡的文字量,即magic number。总是应该使用const或者枚举来定义各种符号常量。如const double PI = 3.14159,enum { NUMBER=128 }。