C语言是一个强大灵活的工具。
我们怎样才能避免C语言中的这些问题呢?
最重要的规避技巧是,知道自己在做什么。
大多数错误都出现在制作者在上床睡觉之前做的最后意见工作上。所以,在准备
最后做一点什么之前,你还是早点休息吧。
在实际组合程序之前想清楚应该如何组合,对得到一个可靠的结果至关重要。
建议:
不要说服自己相信“皇帝的新装”。
while (c == '\t' || c = ' ' || c == '\n')
c = getc(f);
C语言中这是非法的。
相当于下面的代码:
while ((c == '\t' || c) = (' ' || c == '\n'))
c = getc(f);
(c == '\t' || c)不能出现在赋值运算符的左侧。
while (c == '\t' || c == ' ' || c == '\n')
c = getc(f);
直接了当的表名意图。
请使用括号或者其他方式让你的意图尽可能清楚明了。
有时候我们还应该预料那些错误有可能出现,在代码的编写方式上做到事先预防。
while ('\t' == c || ' ' == c || '\n' == c)
c = getc(f);
考察最简单的特例。
适用于程序的设计,构思程序的工作方式,测试程序的工作情况。
使用不对称边界。
注意潜伏在暗处的Bug。
坚持只使用C语言中众所周知的部分。
防御性编程
对程序用户和编译器事先的假设不要过多。
再怎么不可能发生的事情,在某些时候还是有可能发生的。要实现一个健壮的程序,就应该预先
考虑到这种异常情况。
一个C编译器要想严格检测程序中的各种错误,就要对程序中本意是可移植的部分进行严格检测,同时对程序中那些用来完成与特定机器相关的部分网开一面。
另一个原因,某些类型的错误从本质上说是难于检测的。
void set(int *p, int n) {
*p = n;
}
需要上下文来说明程序是否合法。
//2.
//legal
int a[10];
set(a + 5, 37);
//illegal
int a[10];
set(a + 10, 37);
ANSI C标准允许程序得到数组尾端出界的第一个位置的地址。