(转载)你好,C++(20).4.2.2 表达并列条件选择的switch语句:如果……如果……如果……

4.2.2  表达并列条件选择的switch语句:如果……如果……如果……

在现实世界中,还有这样一类特殊的条件选择:

如果明天是晴天,我就穿T恤;

如果明天是阴天,我就穿衬衣;

如果明天是雨天,我就穿外套。

之所以说这是条件选择,是因为它根据不同的情况执行了不同的动作;而之所以说它特殊,是因为这些不同情况(晴天、阴天、雨天)属于同一条件(天气情况)。只要是条件判断,我们就可以用if语句将其表达出来,利用前面介绍过的if…else if…并列条件选择语句,我们可以将这个看天穿衣的场景表达如下:

// 用并列条件选择实现的看天穿衣
#include <iostream>

using namespace std;

// 枚举可能的天气情况
enum Weather
{
    SUNNY = 1,   // 晴天,指定其值为1
    CLOUDY,      // 阴天,其值递增为2
    RAINY,       // 雨天,其值递增为3
};

int main()
{
    cout<<"请输入明天的天气(1-晴天;2-阴天;3-雨天):";
    int nW = 0;
    // 获取用户输入天气情况
    cin>>nW;

    // 对天气情况进行判断
    if(SUNNY == nW) // 如果是晴天
    {
         // 输出晴天该穿的衣服
         cout<<"晴天穿T恤"<<endl;
    }
    else if(CLOUDY == nW) // 如果是阴天
    {
         cout<<"阴天穿衬衣"<<endl;
    }
    else if(RAINY == nW) // 如果是雨天
    {
         cout<<"雨天穿外套"<<endl;
    }
    else
    {
        cout<<"不知道明天是什么天气,你爱穿什么穿什么吧"<<endl;
    }

    return 0;
}

使用并列条件选择语句,虽然能够把这种并列选择场景表达出来,可是我们不得不书写多个if…else if…分支,要书写多个相似的条件表达式,显得有些繁琐。为了简化代码,同时为了使这种并列条件选择表达得更加清晰,C++提供了专门的switch语句以代替复杂的并列条件选择语句,其语法格式如下:

switch( 条件量 )
{
 case 常量值1:
{
  语句1;
}
break;
case 常量值2:
{
    语句2;
}
break;
//…
case 常量值n:
{
    语句n;
}
break;
default:
{
    默认语句;
}
}

其中,条件量就是要进行判断的条件,它可以是某个变量,比如,我们这里表示天气状况的nW变量,也可以是某个更加复杂的表达式。而多个常量值就是这个条件量可能的取值,比如,我们这里的条件量nW的可能取值就是SUNNY(晴天)、CLOUDLY(阴天)或者RAINY(雨天)。在执行的时候,switch语句会首先计算条件量的值,然后将这个值按照从上到下的顺序依次与各个case分支的常量值进行比较。如果两者相等,则进入相应case分支执行,直到遇到分支中的break关键字,结束整个switch语句的执行;如果两者不相等,则继续向下判断后面的case分支。如果直到最后都没有遇到与条件量相等的常量值,则进入表示默认情况的default分支开始执行最终完成整个switch语句。default分支表示对所有不符合case分支条件的例外情况的默认处理,它是可选的,如果我不需要处理例外情况,就可以省略掉default分支。如果没有default分支,而同时又找不到匹配的case分支时,程序则不执行任何语句而直接结束switch语句,如图4-2所示。

图4-2  switch语句的执行流程

有了switch语句,我们就可以用它替换if…else if…并列条件选择语句,将“看天穿衣”的并列条件选择简化为:

// 用switch语句实现的并列条件选择

// 以表示天气状况的nW作为条件量,根据不同的天气穿不同的衣服
switch(nW)
{
    case SUNNY: // 以表示晴天的SUNNY作为常量值,进行对晴天状况的处理
         cout<<"晴天穿T恤"<<endl;
    break;// 完成对晴天状况的处理,用break结束整个switch语句
    case CLOUDY:  // 处理阴天
         cout<<"阴天穿衬衣"<<endl;
    break;
    case RAINY:  // 处理雨天
         cout<<"雨天穿外套"<<endl;
    break;
    default:// 对例外情况进行默认的处理
         cout<<"不知道这是什么天气,你爱穿什么穿什么吧"<<endl;
}

在这里,我们用表示天气状况的变量nW作为条件量,而用标识各种天气状况的枚举值作为各个case分支的常量值。在执行的时候,switch语句会将保存了天气状况的条件量nW从上往下地与各个case分支的常量值进行相等比较,也就相当于并列条件选择语句中的“if(SUNNY == nW)”这样的条件判断。这种相等比较从上到下依次进行,直到遇到两者相等的分支,则进入执行,随后遇到break关键字而结束整个switch语句的执行。这样,switch语句实现的逻辑判断跟之前用if…else if…并列条件选择语句实现的完全一致,而代码却更加简洁,而且各种情况用case分支单独列出,逻辑也更加清晰。所以,在表达这种针对同一条件不同情况的条件选择时,我们应该优先选择使用switch语句。

在使用switch语句时需要特别注意的是每个case分支末尾的break关键字。它的作用是跳(break)出当前的case分支,结束整个switch语句的执行。在上面的例子中,如果用户输入的nW是1,表示明天是晴天。因为SUNNY分支的值跟nW相等,那么switch语句会进入“case SUNNY”分支执行,输出:

晴天穿T恤

接着遇到break关键字,就会忽略掉后面的其他case分支而直接结束整个switch语句的执行。而如果这里没有break关键字,它就会继续向下执行后继的case分支,直到遇到break关键字或者是其后的所有分支执行完毕。所以,如果这个switch语句中缺少了break关键字, 那么用户输入1,输出就成了:

晴天穿T恤

阴天穿衬衣

雨天穿外套

不知道这是什么天气,你爱穿什么穿什么吧

看看,整个都乱套了!所以,在使用switch语句时,一定要注意在每个case分支末尾加上break关键字,表示这个分支处理完毕,结束整个switch语句的执行。

当然,事无绝对。大多数时候,我们需要在每个case分支后加上break关键字,而在某些特殊情况下,也就是多个case分支有共同的功能需要完成时,一个case分支功能是另外一个case分支功能的一部分,两个case分支有包含与被包含的关系,这时也可以有意地去掉包含分支中的break关键字,并将其放在靠上的位置,从而达到共用被包含分支中实现公共功能的代码。例如,我们在KFC点餐时,有汉堡套餐和鸡翅套餐可供选择。汉堡套餐就是一个汉堡而已,而鸡翅套餐是在汉堡套餐的基础上再加一对鸡翅而成。在这个场景下,两个case分支(汉堡套餐和鸡翅套餐)就有了公共功能(一个汉堡),而且两者形成了包含与被包含的关系(鸡翅套餐包含汉堡套餐,而汉堡套餐被鸡翅套餐包含),在这种情况下,就可以省略掉包含case分支(鸡翅套餐)的break关键字,并将其放在相对靠上的位置,以实现共用公共功能:

cout<<"请选择您需要的套餐(1-汉堡套餐;2-鸡翅套餐)"<<endl;
int nOrder = 0;
cin>>nOrder; // 获取用户选择

switch(nOrder)
{
    case 2: // 将包含case分支放在靠上的位置
         cout<<"一对鸡翅"<<endl; // 完成独有的功能
    // 注意,这里省略掉了case分支末尾的break关键字
    case 1: // 将被包含case分支置于靠下的位置
         cout<<"一个汉堡"<<endl; // 完成公共功能
    break; // 保留break关键字,结束switch语句
    default:
         cout<<"无法识别的选项,请重新选择"<<endl;
}

在这个例子中,我们就有意地省略掉了第一个case分支的break关键字,当我们输入1表示选择汉堡套餐时,switch语句会进入“case 1”分支执行,输出“一个汉堡”后,遇到末尾的break关键字,从而结束整个switch语句的执行。最终,我们得到的汉堡套餐的内容是:

一个汉堡

而当我们输入2表示选择鸡翅套餐时 ,switch语句会首先进入“case 2”分支执行,输出“一对鸡翅”后,因为这里没有break关键字,所以它会继续向下进入“case 1”分支执行,输出“一个汉堡”,这时它才遇到break关键字,结束整个switch语句的执行。最终,我们得到的鸡翅套餐的内容是:

一对鸡翅

一个汉堡

这里虽然我们省略了某些case分支末尾的break关键字,但不仅没有造成逻辑上的错误,反而达到了共用公共功能代码的效果。

在使用switch语句时,还需要注意以下几个问题:

(1)  switch关键字后括号中的条件量必须是整型的数值变量或表达式,或者是能够被转换为整型的其他类型,比如字符类型或者枚举类型等。

(2) 因为switch之后的条件量是整型,为了与之比较,所以case之后的常量值也必须是整型。它通常是一些表示各种情况的枚举值,比如上面例子中的SUNNY、CLOUDLY等,也可以直接是常量数字,如上面例子中表示选项的常量数字1和2,甚至可以是只有常量参与运算的常量表达式。

(3) 各个case分支的常量值不能相等,即不能出现两个相同条件的case分支。

原文地址:http://www.cnblogs.com/nihaoCPP/p/4101270.html

时间: 2024-10-10 09:54:19

(转载)你好,C++(20).4.2.2 表达并列条件选择的switch语句:如果……如果……如果……的相关文章

你好,C++(20)如果明天是晴天,我就穿T恤;如果明天是阴天,我就穿衬衣;如果明天是雨天,我就穿外套。——4.2.2 表达并列条件选择的switch语句:如果……如果……如果……

4.2.2  表达并列条件选择的switch语句:如果……如果……如果…… 在现实世界中,还有这样一类特殊的条件选择: 如果明天是晴天,我就穿T恤: 如果明天是阴天,我就穿衬衣: 如果明天是雨天,我就穿外套. 之所以说这是条件选择,是因为它根据不同的情况执行了不同的动作:而之所以说它特殊,是因为这些不同情况(晴天.阴天.雨天)属于同一条件(天气情况).只要是条件判断,我们就可以用if语句将其表达出来,利用前面介绍过的if…else if…并列条件选择语句,我们可以将这个看天穿衣的场景表达如下:

(转载)你好,C++(19)“老师,我这次四级考试过了没有?”——4.2 条件选择语句

4.2  条件选择语句 “老师,我这次四级考试过了没有?” 如果老师被问到这个问题,他会如何回答?是的,他会根据不同的条件选择不同的回答: 如果考试成绩大于等于60,那就回答:“恭喜你,你通过了这次考试”: 否则那就回答“很遗憾,你没有通过这次考试”. 这就是现实世界中的条件选择——根据不同的条件做出不同的动作.那么,在C++程序中,我们又该如何表达这种条件选择呢? 4.2.1  if语句:如果……就…… 在现实世界中,我们总是用“如果……,就……”的句式来表达条件选择,C++也向我们学习,提供

你好,C++(19)“老师,我这次四级考试过了没有?”——4.2 条件选择语句

4.2  条件选择语句 “老师,我这次四级考试过了没有?” 如果老师被问到这个问题,他会如何回答?是的,他会根据不同的条件选择不同的回答: 如果考试成绩大于等于60,那就回答:“恭喜你,你通过了这次考试”: 否则那就回答“很遗憾,你没有通过这次考试”. 这就是现实世界中的条件选择——根据不同的条件做出不同的动作.那么,在C++程序中,我们又该如何表达这种条件选择呢? 4.2.1  if语句:如果……就…… 在现实世界中,我们总是用“如果……,就……”的句式来表达条件选择,C++也向我们学习,提供

(转载)你好,C++(5)如何输出数据到屏幕、从屏幕输入数据与读写文件?

你好,C++(5)如何输出数据到屏幕.从屏幕输入数据与读写文件? 2.2  基本输入/输出流 听过HelloWorld.exe的自我介绍之后,大家已经知道了一个C++程序的任务就是描述数据和处理数据.这两大任务的对象都是数据,可现在的问题是,数据不可能无中生有地产生,C++程序也不可能凭空创造出来数据.那么,C++程序中的数据又从何而来呢? 在现实世界中,国与国之间的交流是通过外交官来完成的.在C++世界中,也有负责应用程序跟外界进行数据交流的外交官,它们的名字就是基本输入/输出流对象(iost

(转载)你好,C++(4)2.1.3 我的父亲母亲:编译器和链接器 2.1.4 C++程序执行背后的故事

你好,C++(4)2.1.3 我的父亲母亲:编译器和链接器 2.1.4 C++程序执行背后的故事 2.1.3  我的父亲母亲:编译器和链接器 从表面上看,我是由Visual Studio创建的,而实际上,真正负责编译源代码创建生成可执行程序HelloWorld.exe的却是Visual Studio中集成的C++编译器cl.exe和链接器link.exe.他们二老,才是我的亲生爹妈. 为了便于人们的编写.阅读和维护,我们的源文件是使用C++这种人们可以理解的高级程序设计语言编写的.然而,计算机却

MyBatis应用开发(20)用delete结点表达数据库记录的删除

1.1. delete 使用delete语句来删除记录. Mapper配置: <!-- deletePerson: 删除一条记录.--> <delete id="deletePerson" parameterType="string"> delete from t_person where id=#{id} </delete> Mapper接口方法: /** * 删除一个t_person记录. * @param id 待删除的pe

switch语句(下)(转载)

之前我们介绍了在switch语句中使用整数类型和枚举类型的情况.这一部分继续介绍使用string类型的情况.string类型是switch语句接受的唯一一种引用类型参数. 下面来看一段C#代码. 代码1 - 使用string类型参数的switch语句 代码1展示的方法中只有一个switch语句,它接收一个字符串类型的参数s,并根据6种不同的情况显示不同的文字.它将被编译器翻译成什么样子的代码呢?这个switch语句是否依然能利用IL中的switch指令呢? 答案马上揭晓.且看由代码1得到的IL,

(转载)你好,C++(22) 排排坐,吃果果——4.3.3 for循环:某个范围内…每个都…

你好,C++(22) 排排坐,吃果果——4.3.3 for循环:某个范围内…每个都… 4.3.3  for循环:某个范围内…每个都… 既然while语句和do…while…语句都已经可以满足我们表达循环现象的需要,那为什么C++还要专门提供for语句来表达循环现象呢?在现实世界中,常常有这样一类特殊的循环现象,例如: 在公司100000个员工范围内,每个员工都增加10000元工资; 在从1到100这个范围内,每个数字都累加到总和中. 说这些是循环现象,是因为它们的动作(增加工资.累加)会循环往复

你好,C++(22) 排排坐,吃果果——4.3.3 for循环:某个范围内…每个都…

4.3.3  for循环:某个范围内…每个都… 既然while语句和do…while…语句都已经可以满足我们表达循环现象的需要,那为什么C++还要专门提供for语句来表达循环现象呢?在现实世界中,常常有这样一类特殊的循环现象,例如: 在公司100000个员工范围内,每个员工都增加10000元工资; 在从1到100这个范围内,每个数字都累加到总和中. 说这些是循环现象,是因为它们的动作(增加工资.累加)会循环往复反复多次地执行.而说它们特殊,是因为这些动作总是在某个范围内(100000个员工范围内