关于判断语句,其else的位置,往往决定了它属于哪个if。一些习题在考查的时候,往往会去掉判断语句的大括号(实际工作中并不建议这样做),更增加了判断else归属的难度。
1. 简单的else归属问题
最简单的else归属判断当然属于有大括号的一类,这样的话,if的大括号括到哪儿,接下来跟着的else就属于这个if。比如下面的语句:
int main(){
int x = 5;
int y = -5;
if(x > 0)
{
if(y > 0)
printf("2\n");
else
printf("3\n");
}
else
{
printf("4\n");
}
return 0;
}
显然,有点C语言基础的,都知道else归属于最上面的if,输出结果为:
3
好,我们再来看下一个。
2. 难一点的else归属问题
如果把大括号去掉呢,再来看下面的代码:
int main(){
int x = 5;
int y = -5;
if(x > 0)
if(y > 0)
printf("2\n");
else
printf("3\n");
printf("4\n");
return 0;
}
如果你更细心一些, 也会知道输出应该是:
3
4
因为如果不加大括号,if或者else默认只会将临近的第一条语句作为分支语句。
所以,第一个if后面,跟着的if和else语句,是一个整体,而这个整体,作为了第一个if的分支语句。
同理,printf("4\n"),这条语句,并不属于任何一个if分支结构。所以不论怎样,它都会执行。不信的话,可以改变x和y的值,你会发现,4始终被输出。
x=5, y=5时,输出为2和4
x=-5,y=+5(或者-5)时,输出为4
3. 再难一点的else归属问题
细心的同学会发现上面的代码中,只有一个else。
好,我们现在把另外一个else加上,代码如下:
int main(){
int x = -5;
int y = -5;
if(x > 0)
if(y > 0)
printf("2\n");
else
printf("3\n");
else
printf("4\n");
return 0;
}
如果理解了第2小节的内容,你会很容易的明白,第二个else为什么属于第一个if。因为中间的if和else语句,仍然作为一个整体,由于没有大括号,所以第一个if的作用范围截止到printf("3\n")这条语句。输出为:
4
4. 应该是最难的else归属问题了
再细心的同学会发现,我们这里没有printf("1\n")这条语句呀,强迫症根本不能忍好吧。
好,我们再把它加上。
int main(){
int x = 5;
int y = -5;
if(x > 0)
printf("1\n");
if(y > 0)
printf("2\n");
else
printf("3\n");
else
printf("4\n");
return 0;
}
看起来没什么不妥,那么这个程序的执行结果应该是多少呢。
答案是,程序编译失败。查看下出错信息:
test.c: In function ‘main’:
test.c:11: error: ‘else’ without a previous ‘if’
如果你上面的内容全部理解了,再看到这条出错的信息后,应该会立刻明白。
我们都知道,不加大括号时,第一个if的作用范围,默认只会有一条语句。
此处,这条语句就是我们刚刚添加的printf("1\n"),由于第一个if的作用范围已经被这条语句占用了,所以下面接着的if和else结构,是独立开来的,并不受第一个if的影响。
此时,如果再加上一个else,也就是代码中的最后一个else,明显会多余,因为这个else找不到和它配对的if。第一个if的作用范围已经失效,第一个if被第一个else占用了。
所以,它是个单身狗。
类似的还有如下的程序:
int main(){
int x = 5;
int y = -5;
if(x > 0)
if(y > 0)
printf("2\n");
else
printf("3\n");
printf("4\n");
else
return 0;
}
这些程序,都会产生编译错误。
所以,写程序的时候,也请考虑单身else的感受,加上大括号!