zoukankan      html  css  js  c++  java
  • 你好,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分支。

  • 相关阅读:
    Generate Parentheses
    Length of Last Word
    Maximum Subarray
    Count and Say
    二分搜索算法
    Search Insert Position
    Implement strStr()
    Remove Element
    Remove Duplicates from Sorted Array
    Remove Nth Node From End of List
  • 原文地址:https://www.cnblogs.com/nihaoCPP/p/switch.html
Copyright © 2011-2022 走看看