C Primer Plus(6) 中文版 第7章 C控制语句:分支和跳转 7.7 多重选择:switch和break

发布于:2023-01-15 ⋅ 阅读:(173) ⋅ 点赞:(0)

7.7 多重选择:switch和break
有时程序需要在多个选项中进行选择。可以用if...else if...else来完成。但是,大多数情况下使用switch语句更方便。
如何使用switch语句的例子:
/* animals.c -- uses a switch statement */
#include <stdio.h>
#include <ctype.h>
int main(void)
{
    char ch;
    
    printf("Give me a letter of the alphabet, and I will give ");
    printf("an animal name\nbeginning with that letter.\n");
    printf("Please type in a letter; type # to end my act.\n");
    while ((ch = getchar()) != '#')
    {
        if('\n' == ch)
            continue;
        if (islower(ch))     /* lowercase only          */
            switch (ch)
        {
            case 'a' :
                printf("argali, a wild sheep of Asia\n");
                break;
            case 'b' :
                printf("babirusa, a wild pig of Malay\n");
                break;
            case 'c' :
                printf("coati, racoonlike mammal\n");
                break;
            case 'd' :
                printf("desman, aquatic, molelike critter\n");
                break;
            case 'e' :
                printf("echidna, the spiny anteater\n");
                break;
            case 'f' :
                printf("fisher, brownish marten\n");
                break;
            default :
                printf("That's a stumper!\n");
        }                /* end of switch           */
        else
            printf("I recognize only lowercase letters.\n");
        while (getchar() != '\n')
            continue;      /* skip rest of input line */
        printf("Please type another letter or a #.\n");
    }                        /* while loop end          */
    printf("Bye!\n");
    
    return 0;

/* 输出:

*/

7.7.1 switch语句
要对紧跟在关键字switch后圆括号中的表达式求值。然后程序扫描标签列表,直到发现一个匹配的值为止。然后程序跳转至那一行。如果没有匹配的标签,如果有default:标签行,就跳转至该行;否则,程序继续执行在switch后面的语句。
break让程序离开switch语句,跳至switch语句后面的下一条语句。如果没有break语句,就从匹配标签开始执行到switch末尾。
顺带一提,break语句可用于循环和switch语句中,但是continue只能用于循环中。尽管如此,如果switch语句在一个循环中,continue便可作为switch语句的一部分。这种情况下,就像在其他循环中一样,continue让程序跳出循环的剩余部分,包括switch语句的其他部分。
如果只希望处理某个标签的语句,就必须在switch语句中使用break语句。另外,C语言的case一般都指定一个值,不能使用一个范围。
switch在圆括号中的测试表达式的值应该是一个整数值(包括char类型)。case标签必须是整数类型(包括char类型)的常量或整型常量表达式(即,表达式中只包含整型常量)。不能用变量作为case标签。switch的构造如下:
switch( 整型表达式 ){
    case 常量1:
        语句 <--可选
    case 常量2:
        语句 <--可选
    default: <--可选
        语句 <--可选
}
7.7.2 只读每行的首字符
只读每行的首字符,丢弃一行中其他字符的行为,经常出现在响应单字符的交互程序中。可以用下面的代码实现这样的行为:
while( (getchar()) != '\n' ){
    continue; /*跳过输入行的其余部分*/ 

循环从输入中读取字符,包括按下Enter键产生的换行符。注意,函数的返回值并没有赋给ch,以上代码所做的只是读取并丢弃字符。
由于最后丢弃的字符是换行符,所以下一个被读取的字符是下一行的首字符。 
假设用户一开始就按下Enter键,那么程序读到的首个字符就是换行符。下面的代码就是处理这种情况:
if( ch == '\n' ){
    continue;

7.7.3 多重循环
可以在switch语句中使用多重case标签。
// vowels.c -- uses multiple labels
#include <stdio.h>
int main(void)
{
    char ch;
    int a_ct, e_ct, i_ct, o_ct, u_ct;
    
    a_ct = e_ct = i_ct = o_ct = u_ct = 0;
    
    printf("Enter some text; enter # to quit.\n");
    while ((ch = getchar()) != '#')
    {
        switch (ch)
        {
            case 'a' :
            case 'A' :  a_ct++;
                break;
            case 'e' :
            case 'E' :  e_ct++;
                break;
            case 'i' :
            case 'I' :  i_ct++;
                break;
            case 'o' :
            case 'O' :  o_ct++;
                break;
            case 'u' :
            case 'U' :  u_ct++;
                break;
            default :   break;
        }                    // end of switch
    }                        // while loop end
    printf("number of vowels:   A    E    I    O    U\n");
    printf("                 %4d %4d %4d %4d %4d\n",
           a_ct, e_ct, i_ct, o_ct, u_ct);
    
    return 0;
}  

/* 输出:

*/

严格地说,case 'U'的break语句并不需要。因为即使删除这条break语句,程序流会接着执行switch中的下一条语句,即default:break;。
所以,可以把case 'U'd的break语句去掉以缩短代码。但是从另一方面看,保留这条break语句可以防止以后在添加新的case时遗漏break语句。
在该例中,如果使用ctype.h系列的toupper()函数可以避免使用多重标签,在进行测试之前就把字母转换成大写字母。
while( (ch = getchar()) != '#' ){
    ch = toupper( ch );
    switch( ch ){
        case 'A': a_ct++;
            break;
        case 'E': e_ct++;
            break;
        case 'I': i_ct++;
            break;
        case 'O': o_ct++;
            break;
        case 'U': u_ct++;
            break;
        default: break; 
    } //switch结束 
} //while循环结束
或者,也可以先不转换ch,把toupper(ch)放进switch的测试条件中:switch(toupper(ch))。
小结:带多重选择的switch语句
一般注解:
程序根据expression的值跳转至相应的case标签处。然后,执行剩下的所有语句,除非执行到break语句进行重定向。
形式:
switch( expression ){
    case label1: statement1 //使用break跳出switch
    case label2: statement2
    default:     statement3 

可以有多个标签语句,default语句可选。
7.7.4 switch和if else
如果是根据浮点类型的变量和表达式来选择,就无法使用switch。如果根据变量在某范围内决定程序流的去向,使用switch就很麻烦。
这种情况用if就很方便。
if( integer < 1000 && integer > 2 )
使用switch要涵盖以上范围,需要为每个整数(3~999)设置case标签。但是,如果使用switch程序通常运行快一些,生成的代码少一些。 

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到