首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

前面使用的if语句在指定的条件为true时执行一个语句。接着,程序按顺序执行下一个语句。当然,有时我们希望只有在条件为false时才执行某个语句或语句块。为此,就要扩展if语句,允许在条件为true时执行一组动作,在条件为false时执行另一组动作。之后,程序按顺序执行下一个语句。这描述为if-else语句。

if-else组合提供了两个选项供选择,其一般逻辑如图4-2所示。

图4-2 if-else语句的逻辑

图4-2中的流程图指出了语句的执行顺序取决于if条件为true还是false。如图所示,在可以使用语句的地方,总是可以使用一个语句块来代替。这就允许为if-else语句的每个选项执行任意多条语句。

仍然使用char类型的变量,编写一个if-else语句,报告存储在变量letter中的字符是否为字母或数字。

if(std::isalnum(letter))

std::cout << "It is a letter or a digit." << std::endl;

else

std::cout << "It is neither a letter nor a digit." << std::endl;

这个程序使用了<cctype>头文件中的函数isalnum()。如果变量letter包含字母或数字,函数isalnum()就返回一个正整数。因为if语句把这个看作是true,所以显示第一个消息。如果变量letter包含的不是字母或数字,函数isalnum()就返回0。对于if来说,这会自动转换为false,执行else之后的输出语句。

程序示例4.5—— 扩展if语句

下面用一个例子来演示if-else语句,这次测试的是数值:

//Program 4.5 Using the if-else

#include <iostream>

using std::cin;

using std::cout;

using std::endl;

int main() {

long number=0; //Store input here

cout << "Enter an integer less than 2 billion: ";

cin >> number ;

cout << endl;

if (number % 2L ==0) //Test remainder after division by 2

cout << " \n Your number is even." //Here if remainder is 0

<< endl;

else

cout << " \n Your number is odd." //Here if remainder is 1

<< endl;

return 0;

}

这个程序的输出如下所示:

Enter an integer less than 2 billion: 123456

Your number is even.

例子的说明

在把输入的值读入number之后,就在if条件中测试该数除以2的余数(使用第2章介绍的取余运算符%),检查它是否为0。整数除以2后的余数只能是1或0,程序中的代码进行了注释。如果余数等于0,if条件就是true,执行if之后的语句。如果余数等于1,则if条件为false,就执行else关键字后面的语句。在输出结果后,执行return语句,结束程序。

注释:

else关键字的后面没有分号,这与语句中的if一样。这里也采用了缩进格式,作为各个语句之间关系的可视化指示符。可以清楚地看出哪个语句在得到true时执行,哪个语句在得到false时执行。在程序中,应总是缩进语句,显示它们的逻辑结构。

在这个例子中,演示了编写if条件的另一种方式。在转换为bool类型时,任何非0值都是true,而0值转换为false。所以,可以把模式化操作的结果用作条件,而不需要比较它和0值。这样,if-else语句就变成:

if(number % 2L) //Test remainder after division by 2

cout << " Your number is odd." //Here if remainder is 1

<< endl;

else

cout << " Your number is even." //Here if remainder is 0

<< endl;

if和else子句需要调换,因为如果number的值是偶数,则(number % 2L == 0)就返回true,而(number % 2L)会转换为false。初看起来这似乎有点让人迷惑,但这个条件的第一个版本如下:

“余数为0是true吗?”

由于1会转换为true,因此,该条件的第二个版本应如下:

“余数是1吗?”

嵌套的if-else语句

前面介绍了如何在if语句中嵌套if语句。显然,也可以在if语句中嵌套if-else语句,在if-else语句中嵌套if语句,在if-else语句中嵌套其他if-else语句,这样就提供了极大的灵活性(同时也很容易出现混淆),下面就举几个例子。先看第一种情况,在if语句中嵌套if-else语句:

if(coffee=='y')

if(donuts=='y')

std::cout << " We have coffee and donuts ."

<< std::endl;

else

std::cout << " We have coffee, but not donuts."

<< std::endl;

其中,coffee和donuts是char类型的变量,其值分别是'y'和'n'。由于对donuts的测试仅在coffee测试的结果为true时才进行,因此在每种情况下,消息都会反映正确的情形。else属于donuts测试中的if语句。这很容易引起混淆。

如果编写这些代码时,缩进格式有错误,就会推导出错误的结论:

if(coffee=='y')

if(donuts=='y')

std::cout << std::endl

<< "We have coffee and donuts .";

else //This else is indented incorrectly

std::cout << " We have no coffee…" //Wrong!

<< std::endl;

代码的缩进让人错误地认为if语句嵌套在if-else语句中,实际上并非如此。第一个消息是正确的,但执行else后的结果就是错误的。这个语句仅在对coffee的测试为true时才执行,因为else属于donuts的测试,不属于coffee的测试。这个错误很容易看出,但if结构越大就越复杂,就越需要弄清楚哪个if拥有哪个else。

注意:

else总是属于前面最接近的那个if(只要另一个else还不属于这个if)。这种混淆称为else悬挂问题。

在程序中,只要一组if-else语句看起来有些复杂,就可以应用这个规则,对该组语句排序。在编写程序时,应总是使用花括号,使代码更清晰。在这样简单的情形中不需要使用花括号,但可以把上一个例子改写为:

if(coffee=='y') {

if(donuts=='y')

std::cout << "We have coffee and donuts ."

<< std::endl;

else

std::cout << " We have coffee, but not donuts."

<< std::endl;

}

现在代码非常清晰了,else肯定属于测试donuts的if语句。

理解嵌套的if语句

知道了规则后,理解if语句嵌套在if-else语句的情形就比较容易了:

if(coffee=='y') {

if(donuts=='y')

std::cout << " We have coffee and donuts ."

<< std::endl;

}

else if(tea=='y')

std::cout << " We have no coffee, but we have tea"

<< std::endl;

提示:

注意这里的代码格式。一个if语句嵌套在else的下面,可以把else和if写在一行上,本书后面的例子就是这样编写的。

这次,花括号是必不可少的。如果省略了花括号,else就属于测试donuts的if语句了。在这种情况下,很容易忘记加上花括号,生成一个很难找出的错误。有这种错误的程序也会编译,因为代码是完全正确的。有时甚至结果也是正确的,但它没有表达出我们真正的意图。

如果在这个例子中删除花括号,则只要coffee和donuts都等于'y',就不会执行if(tea == 'y')检查,从而得到正确的结果。

最后,看看一个if-else语句嵌套在另一个if-else语句中的情况。即使只有一层嵌套,也可能非常混乱。最好对coffee和donuts进行彻底的分析,再开始使用这种嵌套:

if(coffee=='y')

if(donuts=='y')

std::cout<< " We have coffee and donuts ."

<< std::endl;

else

std::cout<< " We have coffee, but not donuts."

<< std::endl;

else if(tea=='y')

std::cout<< " We have no coffee, but we have tea, and maybe donuts…."

<< std::endl;

else

std::cout<< "No tea or coffee, but maybe donuts…"

<< std::endl;

即使采用了正确的缩进格式,这里的逻辑看起来也不是很明显。不需要使用花括号,因为前面的规则已校验,但如果加上花括号,看起来会更清楚一些:

if(coffee=='y') {

if(donuts=='y')

std::cout<< " We have coffee and donuts ."

<< std::endl;

else

std::cout << " We have coffee, but not donuts"

<< std::endl;

}

else

{

if(tea=='y')

std::cout<< " We have no coffee, but we have tea, and maybe donuts…."

<< std::endl;

else

std::cout<< " No tea or coffee, but maybe donuts…"

<< std::endl;

}

在程序中处理这种逻辑还有更好的方式。如果把足够多的嵌套if语句放在一起,肯定会出错。下一节将简化这个过程。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论