8.7 多重选择:switch和break

C语言学习栏目目录

目录

1、switch语句

2、只读每行的首字符

3、多重标签

小结:带多重选择的switch语句

4、switch和if else


 

源码

使用条件运算符和 if else 语句很容易编写二选一的程序。然而,有时程序需要在多个选项中进行选择。可以用if else if...else来完成。但是,大多数情况下使用switch语句更方便。下程序清单演示了如何使用switch语句。该程序读入一个字母,然后打印出与该字母开头的动物名。

/************************************************************************
功能:  使用switch语句                                                                    
/************************************************************************/
#include <stdio.h>
#include <ctype.h>
int main(void)
{
	char ch;
	printf("给我字母表中的一个字母,我就给一个以这个字母开头的动物名字\n");
	printf("请给出开头,输入 # 结束!\n");
	while ((ch = getchar()) != '#')
	{
		if ('\n' == ch)
			continue;
		if (islower(ch))		//只接受小写字母
			switch (ch)
			{
			case 'a':
				printf("argali,亚洲的一种野生绵羊\n");
				break;
			case 'b':
				printf("babirusa, 东南亚疣猪,一种马来西亚野猪\n");
				break;
			case 'c':
				printf("coati, 科提,类浣熊的哺乳动物\n");
				break;
			case 'd':
				printf("desman, 德斯曼,水生,鼹鼠状生物\n");
				break;
			case 'e':
				printf("echidna, 针鼹,刺食蚁兽\n");
				break;
			case 'f':
				printf("fisher,费舍尔,棕色貂\n");
				break;
			default:
				printf("未完,待续!\n");
			}				// switch结束
		else
			printf("只能小写字母有效.\n");
		while (getchar() != '\n')
			continue;		//跳过输入行的剩余部分
		printf("请输入字母开头或者 #.\n");
	}				// while循环结束
	printf("再见!\n");
	return 0;
}

篇幅有限,我们只编到f,后面的字母以此类推。在进一步解释该程序之前,先看看输出示例:

给我字母表中的一个字母,我就给一个以这个字母开头的动物名字
请给出开头,输入 # 结束!
a
argali,亚洲的一种野生绵羊
请输入字母开头或者 #.
e
echidna, 针鼹,刺食蚁兽
请输入字母开头或者 #.
b
babirusa, 东南亚疣猪,一种马来西亚野猪
请输入字母开头或者 #.
g
未完,待续!
请输入字母开头或者 #.
#
再见!

该程序的两个主要特点是:使用了switch语句和它对输出的处理。我们先分析switch的工作原理。

1、switch语句

要对紧跟在关键字 switch 后圆括号中的表达式求值。在上程序清单中,该表达式是刚输入给 ch的值。然后程序扫描标签(这里指,case 'a' :、case 'b' :等)列表,直到发现一个匹配的值为止。然后程序跳转至那一行。如果没有匹配的标签怎么办?如果有default  :标签行,就跳转至该行;否则,程序继续执行在switch后面的语句。

break语句在其中起什么作用?它让程序离开switch语句,跳至switch语句后面的下一条语句(见下图)。如果没有break语句,就会从匹配标签开始执行到switch末尾。例如,如果删除该程序中的所有break语句,运行程序后输入d,其交互的输出结果如下

给我字母表中的一个字母,我就给一个以这个字母开头的动物名字
请给出开头,输入 # 结束!
d
desman, 德斯曼,水生,鼹鼠状生物
echidna, 针鼹,刺食蚁兽
fisher,费舍尔,棕色貂
未完,待续!
请输入字母开头或者 #.
#
再见!

如上所示,执行了从case 'd':到switch语句末尾的所有语句。

顺带一提,break语句可用于循环和switch语句中,但是continue只能用于循环中。尽管如此,如果switch语句在一个循环中,continue便可作为switch语句的一部分。这种情况下,就像在其他循环中一样,continue让程序跳出循环的剩余部分,包括switch语句的其他部分。C语言的case一般都指定一个值,不能使用一个范围。

switch在圆括号中的测试表达式的值应该是一个整数值(包括char类型)。case标签必须是整数类型(包括char类型)的常量或整型常量表达式(即,表达式中只包含整型常量)。不能用变量作为case标签。switch的构造如下:

switch ( 整型表达式)
{
    case 常量1:
        语句   <--可选
    case 常量2:
        语句   <--可选
    default :  <--可选
        语句   <--可选
}

2、只读每行的首字符

上程序清单的另一个独特之处是它读取输入的方式。运行程序时读者可能注意到了,当输入dab时,只处理了第1个字符。这种丢弃一行中其他字符的行为,经常出现在响应单字符的交互程序中。可以用下面的代码实现这样的行为:

while (getchar() != '\n')
    continue;        //跳过输入行的其余部分 

循环从输入中读取字符,包括按下Enter键产生的换行符。注意,函数的返回值并没有赋给ch,以上代码所做的只是读取并丢弃字符。由于最后丢弃的字符是换行符,所以下一个被读取的字符是下一行的首字母。在外层的while循环中,getchar()读取首字母并赋给ch。

假设用户一开始就按下Enter键,那么程序读到的首个字符就是换行符。下面的代码处理这种情况:

if (ch == '\n')
    continue;

3、多重标签

如下程序清单:

/************************************************************************
功能:可以在switch语句中使用多重case标签                                                                      
/************************************************************************/
#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("输入一些字母; 输入#退出 .\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;
		}					// switch结束
	}						// while循环结束
	printf("元音数个数: 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;
}

假设如果ch是字母i,switch语句会定位到标签为case 'i' :的位置。由于该标签没有关联break语句,所以程序流直接执行下一条语句,即i_ct++;。如果 ch是字母I,程序流会直接定位到case 'I' :。本质上,两个标签都指的是相同的语句。

严格地说,case 'U'的 break 语句并不需要。因为即使删除这条 break 语句,程序流会接着执行switch中的下一条语句,即default : break;。所以,可以把case  'U'的break语句去掉以缩短代码。但是从另一方面看,保留这条break语句可以防止以后在添加新的case(例如,把y作为元音)时遗漏break语句。

下面是该程序的运行示例:

输入一些字母; 输入#退出 .
hello world
#
元音数个数: A   E    I    O     U
       0    1     0     2     0

小结:带多重选择的switch语句

关键字:switch

一般注解:

程序根据expression的值跳转至相应的case标签处。然后,执行剩下的所有语句,除非执行到break语句进行重定向。expression和case标签都必须是整数值(包括char类型),标签必须是常量或完全由常量组成的表达式。如果没有case标签与expression的值匹配,控制则转至标有default的语句(如果有的话);否则,将转至执行紧跟在switch语句后面的语句。

形式:

switch ( expression )
{
    case label1 : statement1//使用break跳出switch
    case label2 : statement2
    default  : statement3
}

可以有多个标签语句,default语句可选。如果choice的值是1或2,打印第1条消息;如果choice的值是3,打印第2
条和第3条消息(程序继续执行后续的语句,因为case  3后面没有break语句);如果choice的值是4,则打印第3条消息;如果choice的值是其他值只打印最后一条消息。

4、switch和if else

何时使用switch?何时使用if  else?你经常会别无选择。如果是根据浮点类型的变量或表达式来选择,就无法使用 switch。如果根据变量在某范围内决定程序流的去向,使用 switch 就很麻烦,这种情况用if就很方便:

if (integer < 1000 && integer > 2)

使用switch要涵盖以上范围,需要为每个整数(3~999)设置case标签。但是,如果使用switch,程序通常运行快一些,生成的代码少一些。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值