这个问题虽然已经为人熟知,而且也并非C语言所独有,但即使是有多年经验的C程序员也常常在此失误过。
考虑下面的程序片段:
if (x == 0) if (y == 0) error();else{ z = x + y; f(&z);}
这段代码中编程者的本意是应该有两种主要情况:x等于0以及x不等于0。对于x等于0的情形,除非y也等于0(此时调用函数error),否则程序不作任何处理;对于x不等于0的情形,程序首先将x与y之和赋值给z,然后以z的地址为参数来调用函数f。
然而,这段代码实际上所做的却与编程者的意图相去甚远。
原因在于C语言中有这样的规则,else始终与同一对括号内最近的未匹配的if结合。如果我们按照上面这段程序实际上被执行的逻辑来调整代码缩进,大致是这个样子:
if (x == 0) { if (y == 0) error(); else { z = x + y; f(&z); }}
也就是说,如果x不等于0,程序将不会做任何处理。如果要得到原来的例子中由代码缩进体现的编程者本意的结果,应该这样写:
if (x == 0) { if (y == 0) error();} else { z = x + y; f(&z);}
现在,else与第一个if结合,即使它离第二个if更近也是如此,因为此时第二个if已经被括号“封装”起来了。
#include int main(){ int x,y; x = 0; y = 1; if(x == 0) { if(y == 0) printf("x == 0 && y ==0\n"); } else { printf("x!=0\n"); } return 0;}
摘自《C陷阱与缺陷》