变量 biggest 将与 x[i++]比较。i的值发生了变化,如果前面关系运算的结果为 false(假),后面 i++的副作用导致结果错误。解决这类问题的一个办法是,确保宏 max 中的参数没有副作用。 希望 a、b、q、r之间维持怎样的关系呢? 考虑一个简单的例子: 3/2,商为1,余数也为 1。此时第 1 条性质得到了满足。(-3)/2 的值应该是多少呢? 如果要满足第 2 条性质,答案应该是-1,但如果是这样,余数就必定是-1,这样第 3 条性质就无法满足了。如果首先满足第3 条性质,即余数是 1,这种情况下根据第 1 条性质则商是-2,那么第 2 条性质又无法满足了。因此,C 语言在实现整数除法截断运算时,必须放弃上述三条原则中的至少一条。大多数程序设计语言选择了放弃第 3 条,而改为要求余数与被除数的正负号相同。 假定一个数 n代表经过某种运算后的结果,希望通过除法运算得到 h,满足 0<=h< HASHSIZE。又如果已知 n 恒为非负,那么只需要像下面一样简单地写: h=n % HASHSIZE; 然而,如果n 有可能为负数,而此时h 也有可能为负,那么这样做就不一定总是合适的了。不过已知 h>-HASHSIZE,可以这样写: 这样,如果不小心把比较运算符==写成了赋值运算符= ,编译器将会捕获到这种错误,并给出诊断信息:试图给字符常量 \t 赋值是非法的。 考查最简单的特例。无论是构思程序的工作方式,还是测试程序的工作情况,这一原则都是适用的。当部分输入数据为空或者只有一个元素时(临界点),很多程序都会执行失败,这些情况应提前就考虑到。 使用不对称边界。C 语言中数组下标取值从 0 开始, 各种计数错误的产生与这一点或多或少有关系。一有旦理解了这个事实,处理这些计数错误就变得不那么困难。 注意潜伏在暗处的 Bug。各种 C 语言实现存在着或多或少的细微差别,应该坚持只使用 C 语言中众所周知的部分,避免使用“生僻”的特性。这样能方便地将程序移植到新的机器或编译器,减少编译问题。 防御性编程。对程序运行或编译器实现的假设不要过多,再怎么不可能发生的事情,某些时候还是有可能发生的,一个健壮的程序应该预先考虑到这些异常情况。可参考《动态内存管理及防御性编程》。 结束...main(){
FILE*fp;fp=fopen(file,
FILE*fp;
fun(){
errno=
biggest=x[
biggest=((biggest)>(x[i++])?(biggest):(x[i++]));
(资料图片)
biggest=x[
q=a/b;r=a%b;
h=n%HASHSIZE;
{
while("\t"=c||""==c||"\n"==c)c=getc(f);