6.1.3 嵌套的if语句
讨论if语句的一般格式时,我们指出:如果圆括号中表达式的求值结果是TRUE,将执行之后的语句。如果这条程序语句是另外一条if语句,也是完全合法的,如以下语句:
if([chessGame isOver]==NO)
if([chessGame whoseTurn]==YOU)
[chessGame yourMove];
如果向chessGame发送的isOver消息所返回的值为NO,将执行随后的语句,它是另一条if语句。这条if语句比较从whoseTrun方法返回的值与YOU。如果这两个值相等,将向chessGame对象发送yourMove消息。因此,只有在两边的对弈都未结束且轮到你移动棋子时,才发送yourMove消息。事实上,使用复合关系可将这条语句等价地表示成以下形式:
if([chessGame isOver]==NO&&[chessGame whoseTurn]==YOU)
[chessGame yourMove];
对于嵌套的if语句,更实际的例子可能是对上述例子添加了else子句之后的形式,如下所示:
if([chessGame isOver]==NO)
if([chessGame whoseTurn]==YOU)
[chessGame yourMove];
else
[chessGame myMove];
这条语句的执行方式和前面描述过的相同。然而,如果对弈没有结束并且不该你移动棋子,将执行else子句。这将向chessGame发送消息myMove。如果对弈结束,就会跳过后面整个if语句,包括对应的else子句。
要注意else子句如何与if语句对应,即用于测试从whoseTurn方法返回的值的if语句,而非用于测试对弈是否结束的if语句。一般规则是:else子句通常与最近的不包含else子句的if语句对应。
在上述例子中,可进一步为最外层的if语句添加else子句。这条else子句将在对弈结束时执行:
if([chessGame isOver]==NO)
if([chessGame whoseTurn]==YOU)
[chessGame yourMove];
else
[chessGame myMove];
else
[chessGame finish];
当然,即使使用缩进来表明你认为Objective-C语言解释语句的方式,但它并不总是与系统实际解释语句的方式一致。例如,从上述例子中删除第一个else子句
if([chessGame isOver]==NO)
if([chessGame whoseTurn]==YOU)
[chessGame yourMove];
else
[chessGame finish];
系统并不会以这种格式解释这条语句。而是使用以下形式解释这条语句:
if([chessGame isOver]==NO)
if([chessGame whoseTurn]==YOU)
[chessGame yourMove];
else
[chessGame finish];
这是因为else子句与最近的无else子句的if语句对应。在最内部的if语句不包含else子句,但外部的if语句却包含else子句的情况下,可用花括号强制表示不同的关联。花括号具有隔离if语句的作用。因此,
if([chessGame isOver]==NO){
if([chessGame whoseTurn]==YOU)
[chessGame yourMove];
}
else
[chessGame finish];
可实现所希望的结果。