第6章 选择结构程序设计
顺序结构程序设计最简单,但通常无法解决生活中的选择性问题。选择结构程序设计需要用到一些条件判断语句,可实现的程序功能更加复杂,程序的逻辑性与灵活性也更加强大。
本章致力于使读者掌握使用if语句进行条件判断的方法,并掌握switch语句的使用方式。
本章的知识架构及重难点如下:
6.1 if语句
日常生活中,为了使交通畅通有序,一般会在路口设立交通信号灯。信号灯为绿色时,车辆可以行驶通过;信号灯为红色时,车辆就要停止行驶。可见,信号灯给出了信号,人们通过不同的信号进行判断,然后根据判断的结果进行相应的操作。
在C语言程序中,要想完成这样的判断操作,利用的就是if语句。if语句的功能就像路口的信号灯一样,通过判断不同的条件,决定是否进行操作。
程序开发中,会遇到许多类似于红绿灯这样的“决策”,可将其简化成对某个“条件”的检验,进而转换为判断某个表达式的值是真还是假,最后根据真假情况选择性地执行后续的操作。除了没有在何返回值的函数和返回无法判断真假的结构函数,几乎所有表达式的返回值都可以判断真假。
6.2 if语句的基本形式
if语句中,首先判断表达式的值,然后根据该值的真假情况决定后续程序流程。表达式的值不等于0,就表示为真;否则,就是假值。if语句有if、if…else和else if 3种形式,下面介绍每种形式的具体使用方式。
6.2.1 if语句形式
if语句的一般形式如下:
if(表达式)语句
其中,括号中的表达式就是要进行判断的条件,语句则是要执行的对应操作。如果if判断括号中的表达式为真(非0),就执行后面的语句;如果为假(0),则不执行后面的语句。例如下面的代码:
if(iNum)printf("The truevalue");
上述代码中,如果变量iNum的值为真,则执行后面的printf输入语句;如果变量iNum的值为假,则不执行后面的printf语句。
用if语句解决红绿灯问题时,可以约定信号灯为1表示绿灯,则判断代码为:
if(iSignal==1) printf("the Signal Light is %d:",iSignal);
上述代码中,首先判断表达式”iSignal==1"是否成立,如果条件成立,那么判断结果是真值,执行后面的输出语句;如果条件不成立,那么判断结果为假值,不执行后面的输出语句。
前面两处示例代码中,if后的执行部分都只有一条语句。如果有两条语句,又该怎么办呢?这时可以使用大括号,使之成为语句块。例如:
ifCiSignal==1)
{
printf("the Signal Light is %d:\n",iSignal);
printf("Cars can run");
}
将执行的语句都放在大括号中,这样当if语句判断条件为真时,语句块内的内容将会全部被执行。使用这种方式的好处是可以规范、清晰地表达出if语句所包含的范围。建议大家在使用if语句时,都使用大括号将执行语句包括在内。
误区警示:
if语句的括号后一定不要加英文分号(;),否则将编译报错。例如:
if(i>100);
{
sum=i+5000;
printf("%d\n",sum);
}
如果已经报错,可根据错误提示,找到差错并修改代码。
选择结构处理问题一定要把条件描述清楚,例如下面的语句是错误的。
if(i/6<>0){...}
if语句的执行流程图如图6.1所示。
【例6.1】使用if语句模拟打卡签到 模拟此场景:一位职工早上上班打卡,她的工位号是13,密码是111,输入正确门禁卡会出现“谢谢,已签到”的字样。
在本实例中,为了模拟打卡签到,要使用if语句判断工位号和密码。如果工位号是13,同时密码是111,则通过printf函数提示“谢谢,已签到”。
(1)为了模拟打卡签到,要根据工位号和密码情况进行判断,这样就需要两个变量分别表示工位号和密码。在程序代码中,定义变量loc表示工位号,ser表示密码。
(2)输出提示信息,提醒用户输入loc、ser变量的值。此时用键盘输入“13,111”,表示工位号是13,密码是111。
(3)使用if语句判断,如果为真,则表示签到成功;如果为假,则表示签到不成功。因为输入的变量loc的值为13,ser的值是111,表达式loc13&&ser111的条件成立,因此判断的结果为真值,从而执行if语句后面大括号中的语句。
运行程序,显示效果如上图所示。
if语句可以多次使用,使得程序能根据不同的分支条件给出相应的操作。例如在例6.1中,虽然使用if语句对输入的loc、ser变量进行了判断,但是只给出了判断正确,也就是loc等于13、ser等于111时执行的操作,并没有给出判断错误时对应的操作。为了保证在用户输入错误的工位号、密码时,程序也能做出反应,需要再使用一次if语句。现在对例6.1进行完善。
【例6.2】完善模拟打卡签到 例6.1仅对打卡成功情况做出了相应操作,为进一步完善打卡签到失败时的操作,在程序中再添加一次if语句,对打卡签到失败的情况进行判断,并且在条件成立时给出相应操作。
(1)在例6.1的基础上进行修改,完善程序的功能。在代码中添加一个if判断语句,用来表示当loc!=13&&ser!=111时要进行的相应操作。
(2)从程序的开始处来分析整个程序的运行过程。使用scanf函数输入数据,这次用户输入的是“12、123”,表示工位号是12,密码是123。
(3)程序继续执行,第一个if语句判断loc==13&&ser=111是否为真,如果判断的结果为真,则说明签到成功。因为loc的值是 12,ser的值是123,所以判断的结果为假,不会执行第一个printf语句中的内容。
(4)接下来是新添加的if语句,在其中判断loc!=13&&ser!=111是否为真,如果判断成立为真,则表示签到不成功。因为输入的值为12、123,所以loc!=13&&ser!=111条件成立,执行第二个printf语句内容。
运行程序,显示效果如上图所示。
警示:刚开始编程在程序中使用if语句时,常常会将下面的两个判断弄混:
if(value){...} /*判断变量值是否为真*/
if(value==0){...} /*判断表达式的值是否为真*/
这两行代码中都有value变量,value值虽然相同,但是判断的结果却不同。第1行代码判断的是value的值是否为真,第2行代码判断的是value=0这个表达式是否成立。假定其中value的值为0,那么在第一个if语句中,value值为0即说明判断的结果为假,所以不会执行if后的语句。在第二个if语句中,判断的是value是否等于0,因为设定value的值为0,所以表达式成立,那么判断的结果就为真,执行if后的语句。
6.2.2 if…else语句形式
if语句只给出了条件为真时要执行某个操作,并未给出条件为假时具体要干什么。如果想在条件为假时执行另外一段代码,需要利用if…else语句来完成,其一般形式如下:
if(表达式)
{
语句块1;
{
else
{
语句块2;
}
if…else语句的执行流程图如图6.4所示。
在if后的括号中判断表达式的结果,如果判断的结果为真值,则执行if后的语句块内容;如果判断的结果为假值,则执行else后的语句块内容。也就是说,当if语句检验的条件为假时,就执行else后面的语句或者语句块。例如:
if(value)
{
printf("the value is true");
}
else
{
printf("the value is false");
}
注意:
else语句必须跟在一个if语句的后面,不能独立使用。
【例6.3】条件判断真真假假 在本实例中,使用if…else语句判断用户输入的数值。输入的数字为0,表示条件为假;输入的数字为非0,表示条件为真。
(1)程序中定义变量iNumber用来保存用户输入的数据,然后通过if…else语句判断变量的值。
(2)用户输入数据的值为0,if语句判断iNumber变量,此时也就是判断输入的数值。因为0表示的是假,所以不会执行if后面紧跟着的语句块,而会执行else后面语句块中的操作,显示一条信息并将数值进行输出。
(3)从程序的运行结果也可以看出,当if语句检验的条件为假时,就执行else后面的语句或者语句块。
运行程序,显示效果如上图所示。
if…else语句也可以用来判断表达式,根据表达式的结果选择不同的操作。
【例6.4】计算员工工资 某公司的薪酬设计如下:工龄在5年以上,工资=基本工资+全勤奖+2倍的全勤奖;否则,工资=基本工资+全勤奖。本实例利用if…else语句判断并计算工资,具体代码如下:
(1)在程序运行过程中,利用printf函数先显示一条信息,提示用户输入一个数据,例如输入3。这个数据的数值由变量year保存。
(2)if语句判断表达式year>5的真假。如果判断的结果为真,说明工龄大于5,则执行if后的语句,输出“基本工资+全勤奖+2倍的全勤奖”的值;如果判断的结果为假,说明工龄小于等于5,则执行else后的语句,输出“基本工资+全勤奖”的值。因为year的值为3,所以year>5的关系表达式结果为假,这样执行的就是else后的语句,输出“基本工资+全勤奖”的值。
运行程序,显示效果如上图所示。
误区警示:
在使用if语句比较浮点数时,不要使用浮点值,这样就会导致实际结果的偏差,因为浮点值属于近似值。
【例6.5】根据时间输出问候语 输入一个时间,当时间小于12时,输出“Good day";当时间等于12时,输出”Good noon";否则输出"Good evening"。本实例使用if…else语句实现,具体代码如下:
(1)程序运行时,先输出信息,提示用户输入一个时间。
(2)输入数字14,将其保存到变量time中。接下来使用if语句进行判断。
(3)第一个if语句判断time是否小于12,很明显判断结果为假,因此不会执行第一个if后语句块中的内容。
(4)第二个if语句判断time是否小于12,结果为假,因此不会执行第二个if后语句块中的内容。
(5)因为第二个if语句为假值,不执行第二个if语句的话,就会执行else后的语句块输出信息"Good evening"。
运行程序,显示效果如上图所示。
注意:
上面这个程序实际上是存在一些问题的,假如用户输入的数值为5,第一个if语句判断为真值,则会执行后面紧跟着的语句块。紧接着,第二个if语句判断出time值不等于12,为假值,所以会执行else后的语句块,如图6.8所示。注意,else后的语句执行是我们不希望发生的,6.2.3节中会介绍解决这个问题的方法。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b9272315d1d04eb5976f7ccbd5f9aef7.png#pic_center)
6.2.3 else if 语句形式
利用if和else关键字的组合,可以实现else if语句。该语句可对一系列互斥的条件进行检验,从而解决较复杂的判断和决策问题。else if语句的一般形式如下:
if(表达式1)
{
语句块1
}
else if(表达式2)
{
语句块2
}
else if(表达式3)
{
语句块3
}
...
else if(表达式 m)
{
语句块 m
}
else
{
语句块n
}
else if语句的执行流程图如图6.9所示。首先对if语句中的表达式1进行判断,如果结果为真值,则执行后面跟着的语句块1,然后跳过else if语句和else语句,如果结果为假,那么判断else if语句中的表达式2,如果表达式2为真值,那么执行语句块2而不会执行后面else if的判断或者else语句。当所有的判断都不成立,也就是都为假时,执行else后的语句块n。
误区警示:使用多个else if语句时,要格外注意下方的复合语句(即语句块)部分,大括号一定要保证成对匹配。
【例6.6】计算分段函数的值 利用选择结构设计一个程序,使其能计算如下分段函数:
利用选择结构设计一个程序,使其能计算如下分段函数:
当输入x值时,计算显示y值。具体实现代码如下:
(1)程序中使用printf函数显示一条信息,提示用户输入x。
(2)这里假设输入的数字为5,变量x将输入的数值保存,用来执行后续判断。
(3)if语句首先判断x是否小于1,然后else if语句判断x是否大于等于1且小于10,如果都不满足,则会执行else处的语句。因为x的值为5,所以x>=1&&x<10关系表达式为真,执行相应else if处的语句块,输出提示信息。
运行程序,显示效果如上图所示。
【例6.7】学生成绩等级划分 很多小学一、二年级的学生成绩并不显示分数,而是显示为优秀、良好、合格中、不合格4个等级。各等级的划分标准如下。
① 优秀: 大于等于90分。
② 良好:大于等于80分,小于90分。
③ 合格:大于等于60分,小于80分。
④ 不合格:小于60分。
根据控制台输入的成绩,输出与该成绩对应的等级。使用else if语句实现,具体代码如下:
(1)程序中使用printf函数显示一条信息,提示用户进行输入成绩。这里假设输入的成绩是72,变量score将输入的数值保存,用来执行后续判断。
(2)if语句首先判断score是否大于等于90,然后使用else if语句判断score大于等于80且小于90的情况,再使用else if语句判断score大于等于60且小于80的情况,如果都不满足则会执行else处的语句。因为score的值为72,所以score>=60&&score<80关系表达式为真,执行第二个else if 处的语句块,输出提示信息。运行程序,显示效果如上图所示。
编程训练:
训练1:可乐还是咖啡 利用if语句判断用户输入的数值,输出对应的饮品。输入数字1代表喝CocaCola,输入数字2代表喝coffee。运行结果如下:
数字1代表喝CocaCola, 数字2代表喝coffee,请选择:
2
您要喝的是coffee
训练2:模拟交通信号灯情况 “红灯停,绿灯行,黄灯等一等”是我们从小熟知的安全通行口诀。当交通信号灯是红色时,停止通行;为绿灯时,可以通行;为黄灯时,需要等待。用代码模拟红绿灯的当前状态及通行情况,输出结果如下:
数字1表示红灯亮,数字2表示黄灯亮,数字3表示绿灯亮
请输入目前交通灯的状态:
3
目前交通灯是绿灯,可以通行
训练3:模拟抽奖游戏 某公司年会抽奖,抽奖细则如下。
①抽中1,代表中一等奖,奖品是42寸彩电。
②抽中2,代表中二等奖,奖品是光波炉。
③抽中3,代表中三等奖,奖品是加湿器。
④抽中4,代表中安慰奖,奖品是16GB的U盘。
编写代码,根据控制台输入的中奖等级,输出对应的奖品。输出结果如下:
请输入中奖等级:
2
奖品是光波炉
训练4:买彩票中大奖 编写代码模拟某彩民的梦想:如果买彩票中奖,就换辆豪车;如果没中奖,那就该干啥干啥。当然,中奖金额不同,要换的车子也不同。例如,具体的中奖设想如下。
①超过500万元,换兰博基尼。
②在500万元~200万元,换卡宴。
③在200万元~50万元,换奔驰。
④在0~50万元,换奥迪。
⑤没中奖,该吃饭吃饭,该睡觉睡觉。
用if…else if…else语句输入中奖金额,输出要实现的梦想,运行结果如下:
请输入中奖金额:56
我中了56万,买奔驰
6.3 if的嵌套形式
if语句中还可以包含一个或多个if语句,此种情况称为if语句的嵌套。一般形式如下:
if(表达式1)
{
if(表达式2)
{
语句块1
}
else
{
语句块2
}
}
else
{
if(表达式3)
{
语句块3
}
else
{
语句块4
}
}
``
使用if语句的嵌套形式,可将判断的条件进行细化,从而实现更复杂的判断和操作。
这就好比人们在生活中随时在进行的多重判断和选择。每天早上醒来,我们通常会想一下今天是周几,如果是周末,就是休息日;如果不是周末,就要上班。同时,休息日可以是星期六,也可以是星期日,星期六我们可以和朋友去逛街,星期日我们可以陪家人在家。工作日如果是星期一,就要开工作例会,其他时间则正常上班。
如何用if语句来实现上述判断呢?这里就要用到if嵌套语句。外层if语句的表达式1用于判断今天是否是周末,如果判断结果为真,则用一个嵌套if...else语句,通过表达式2判断今天是否是星期日,然后再判断今天是不是星期六。如果为星期六,就陪朋友逛街;如果为星期日,就陪家人在家。接下来返回外层,用else语句给出不是周末时的情况。这里同样要嵌套一个if...else语句,通过表达式3判断是否是周一,如果是就开例会,否则就正常上班。代码如下:
```c
if(iDay>Friday) /*判断为周末的情况*/
{
if(iDay==Saturday) /*判断为星期六时的操作*/
{ }
else /*为星期日时的操作*/
{ }
}
else /*不为周末的情况*/
{
if(iDay==Monday) /*判断为星期一时的操作*/
{ }
else /*其他工作日时的操作*/
{ }
}
注意:
if语句、if...else语句、else if语句可以根据需要互相嵌套。在复杂的嵌套中,一定要注意if与else的配对情况。else总是与其前面最近未配对的if进行配对。
前面曾经介绍过,if语句中如果要执行的操作只有一个语句,可以不写大括号。这里是否也可以呢?修改一下上面的代码,让其先判断是否为工作日,在工作日中只判断星期一的情况,然后再判断周末时的情况。代码如下:
if(iDay<=Friday) /*判断为工作日的情况*/
if(iDay==Monday) /*判断为星期一时的操作*/
{ }
else
if(iDay==Saturday) /*判断为星期六时的操作*/
{ }
else
{ }
写这段代码时,我们的设想是先判断是否为工作日,如果是工作日,则判断是否为星期一;如果不是工作日,则判断是否是星期六,否则就是星期日。但因为else总是与其前面最近且未配对的if进行配对,所以粗体处的else不会与第一个if语句(if(iDay<Friday)配对,而是会与第二个if语句(if(iDay==Monday))配对,从而形成一个整体内嵌语句块,偏离了设计的初衷。此时的递进层次如下:
如果为最外层if语句后的语句块加上大括号,就可避免出现这种情况了。因此,建议大家在条件判断中即使只有一条语句,也要使用大括号进行层次划分。
【例6.8】购买粽子
粽子有甜的,有咸的。甜粽子有5元和10元的,咸粽子有4元和12元的。编写程序,根据输入的口味和钱数,判断并打印出能吃到哪种粽子。其中,输入1代表选择甜粽子,其他数字代表选择咸粽子。用户输入“1”和“12”,输出“您可以吃到10元的甜粽子”。
使用if嵌套语句选择粽子种类,实现具体代码如下:
(1)定义变量type用来保存后面用户输入的粽子口味,定义变量price用来保存用户输入的钱数。
(2)在运行时,这里输入“1”,代表选择甜粽子。if语句首先判断表达式type==1,如果成立,则表示选择的是甜粽子,否则执行else表示咸粽子的部分。如果判断为真,则再利用if语句判断price>=5&&price<10的值,如果条件为真,则输出“您可以吃到5元的甜粽子”。else if语句判断price>=10的值,如果为真,则输出“您可以吃到10元的甜粽子”,else语句表示的是钱数不够,则输出“您不可以吃到甜粽子”。
(3)因为type保存的数值为1,并且price大于10,所以输出信息是“您可以吃到10元的甜粽子”。运行程序,显示效果如上图所示。
编程训练:
训练5:销售等级划分 一个商品可能畅销,也可能滞销。根据输入的商品7天销售数据,输出该商品的销售等级。销售级别划分如下。
①销售量大于1000,级别A。
②销售量小于1000且大于等于500,级别B。
③销售量小于500且大于等于300,级别C。
④销售量小于300,级别D。
使用if嵌套语句,根据输入的7天销售量,输出对应的销售等级。输出结果如下:
训练6:人生不同阶段 利用if嵌套语句输出人生的不同阶段。
①年龄小于13岁,且小于2岁,输出他是婴儿。
②年龄小于13岁,且年龄在2~4岁,输出他正在蹒跚学步。
③年龄小于13岁,且年龄在4~13岁,输出他是儿童。
④年龄大于13岁,且年龄在13~20岁,输出他是青少年。
⑤年龄大于13岁,且年龄在20~65岁,输出他是成年人。
⑥年龄大于13岁,且年龄大于65岁,输出他是老年人。
定义一个变量age,根据age的值,判断处于人生的哪个阶段。运行结果如下:
6.4 条件运算符
首先来用if语句实现对两个数中最大值的求解,代码如下:
if(a>b)
{ max=a; }
else
{max=b;}
上面的代码可以用条件运算符“?:”来简化:
max=(a>b)?a:b;
条件运算符可对一个表达式中值的真假情况进行检验,然后根据检验结果返回另外两个表达式中的一个。条件运算符的一般形式如下:
表达式1?表达式2:表达式3;
在运算中,首先对第一个表达式的值进行检验。如果值为真,则返回第二个表达式的结果值;如果值为假,则返回第三个表达式的结果值。例如,代码 "max=(a>b)?a:b; “中,首先判断表达式a>b是否成立,成立则说明结果为真,否则为假。当为真时,将a的值赋给max变量;如果为假,则将b的值赋给max变量。
【例6.9】计算出租车费用 本实例要求计算出租车的收费情况。出租车行驶时,路径不足3千米,收取起步价6元;路程如果超过3千米,则会在起步价金额上加上超出部分的费用(按每千米2元收费)。使用条件运算符进行判断选择,具体代码如下:
(1)定义变量jour表示公里数,fee表示所花费用。
(2)根据提示信息,用户输入行驶公里数数据。假设用户输入12,表示公里数超3。接下来使用条件运算符判断表达式jour<3是否成立,成立时为真,将”?"号后的值6赋给fee变量;否则将“6+(jour-3)*2"的值赋给fee变量。因为jour<3表达式不成立,所以fee的值为24。
运行程序,显示效果如上图。
编程训练
训练7:校园网收费标准 某校园流量的收费标准是一元一天,如果购买时间超过30天,就按每天(包括30天)0.75元收费,否则就按原价收费。学生输入自己想购买的天数,输出所要花费的费用。输出结果如下:
请输入天数:
65
所花费用是:48.75
训练8:模拟京东自营配送收费 京东自营是京东商城的一大特色,通过在全国建有多个仓库,实现就近发货和快速到货。模拟京东自营的配送收费,满99元即包邮,不满99元加收6元快递费。利用条件运算符编写程序,运行结果如下:
您共计消费
34
您实际需要付40.0元
6.5 switch语句
在实际问题中,常需要用到多分支的选择。当然,使用嵌套的if语句也可以实现多分支选择,但如果分支较多,就会使得嵌套的if语句层数过多,程序冗余,可读性也不好。C语言中可以使用switch语句直接处理多分支选择的情况,将程序代码的可读性提高。
6.5.1 switch语句的基本形式
switch语句是多分支选择语句。一般形式如下:
switch(表达式)
{
case 情况1:
语句块1;
case 情况2:
语句块2;
....
case 情况n:
语句块n;
default:
默认语句块;
}
switch语句的执行流程图如图6.14所示。
switch后面的表达式就是要进行判断的条件,然后使用case关键字表示检验条件符合的各种情况,其后的各语句块是相应的操作。其中还有一个default关键字,作用是如果没有符合条件的情况,那么执行default后的默认情况语句。
说明:switch语句检验的条件必须是一个整型表达式,这意味着其中也可以包含运算符和函数调用。而case语句检验的值必须是整型常量,即常量表达式或者常量运算。
下面通过示例代码分析一下switch语句的使用方法。
switch(selection)
{
case 1:
printf("Processing Receivables\n");
break;
case 2:
printf("Processing Payables\n");
break;
case 3:
printf("Quitting\n");
break;
default:
printf("Error\n");
break;
}
首先switch判断selection变量的值,然后利用case语句检验selection值的不同情况。假设selection的值为2,那么执行case为2时的情况,执行后跳出switch语句。如果selection的值不是case中所列出的情况,那么执行default中的语句。在每一个case或default语句后都有一个break关键字。break语句用于跳出switch结构,不再执行下面的代码。
注意:switch语句中,如果所有case后面的值都不能匹配switch语句的条件,就执行default语句后面的代码。其中,任意两个case语句都不能使用相同的常量值;每个switch结构只能有一个default语句,而且default可以省略。
【例6.10】计算商品折扣金额 某大型商超为答谢新老顾客,当累计消费金额达到一定数额时,顾客可享受不同的折扣。
① 累计未满500元,当前消费不享受任何折扣优惠。
② 累计满500元,当前消费可享受9折优惠。
③ 累计满1000元,当前消费可享受8折优惠。
④ 累计满2000元,当前消费可享受7折优惠。
⑤ 累计满3000元,当前消费可享受6折优惠。
⑥ 累计3000元以上,当前消费可享受5折优惠。
根据顾客购物小票上的消费金额,在控制台上输出该顾客将会享受的折扣与打折后需要支付的金额。在本实例中,要求使用switch语句来判断打折后的金额。具体代码如下:
(1)定义变量grade用来保存折扣等级。计算方法为“折扣等级=购物金额/500元”。
(2)使用switch语句判断整型变量grade,其中使用case关键字检验可能出现的级别情况,并且在每个case语句的最后使用break语句跳出。如果没有符合的情况,则会执行default默认语句。
注意:
在case语句表示的条件后有一个冒号“:”,在编写程序时不要忘记。
运行程序,显示效果如图6.15所示。
switch语句中,每个case情况内都使用了break语句。如果不使用break语句,会出现什么情况呢?break的作用是跳出switch语句,因此如果本例中没有break语句说明,程序后面的内容将会都执行。为了验证猜测是否正确,将上面程序中的break注释掉,运行程序,显示结果如图6.16所示。
从运行结果可以看出,当去掉break语句后,将计算default下的语句,很明显是错误的。因此,break语句在case语句中是不能缺少的。
【例6.11】日程安排 如果是周末就是休息日,如果不是周末就要上班。同时,休息日可以是星期六,也可以是星期日,星期六我们可以和朋友去逛街,星期日我们可以陪家人在家。用switch语句来模拟此场景。
在程序中,使用switch…case进行检验时,不要忘记case检验的条件只能是常量或者常量表达式,而不能对变量进行检验。运行程序,显示效果如上图所示。
误区警示:switch语句时,很容易认为break是switch语句的一部分,是switch的必要条件。但是并不是这样,break可以不与switch匹配。
6.5.2 多路开关模式的switch语句
将某个case语句后的语句块及break去掉之后,可以设计出多路开关模式的switch语句。例如:
switch(表达式)
{
case 1:
语句1
break;
case 2:
case 3:
语句2
break;
...
default:
默认语句
break;
}
可以看到,如果在case2后不使用break语句,那么符合case2检验与符合case3检验时的输出效果是一样的。也就是说,多路开关模式可使得多种检验条件执行同一个操作。
【例6.12】判断一年四季情况 在本实例中,要求使用switch语句判断输入的月份属于哪个季节。已知3、4、5月是春季,6、7、8月为夏季,9、10、11月为秋季,12、1、2月为冬季。
本例程序中使用多路开关模式,使得检测month的值为3、4、5这3种情况时,都会输出相同的结果。同时,利用default语句对不符合月份的数字输入,提示错误。运行程序,显示效果如下图。
编程训练:
训练9:猜猜哪个灯能亮 已知一个灯泡并联3个开关,分别为开关1、开关2、开关3;另有一串彩灯,串联开关4;开关5和开关6并联一个白炽灯和节能灯。电路如图6.19所示。问:随机按下开关,哪个灯能亮。输出结果如下:
训练10:高考填报志愿 高考是人生中最重要的考试。不同的分数可选择不同的大学。根据模拟分数线,输出可以报考哪些大学。
①671分:北京大学。
②661分:清华大学。
③668分:复旦大学。
④664分:上海交通大学。
⑤默认情况:其他大学。
利用switch语句编写程序,最终运行结果如下:
请输入您的高考成绩:664
选择上海交通大学
6.6 if…else语句和switch语句的区别
if…else语句和switch语句都可根据不同的情况检验条件,并做出相应的判断。那么if…else语句和switch语句有什么区别呢?下面从两者的语法和效率方面进行比较。
1.语法的比较
使用时,if需要配合else关键字,switch需要配合case关键字;if语句是先对条件进行判断,而switch语句是后进行判断。
2.效率的比较
if…else结构对少量的检验,判断速度比较快。但是随着检验深度的增长,会逐渐变慢,并且也不容易进行后续的条件添加和扩充。
switch结构中,除default默认情况外,对其他每一项case的检验速度都是相同的。default默认情况比其他情况都快。
当需要判定的情况较少时,使用if…else结构比使用switch结构检验速度快。也就是说,如果分支在3个或者4个以下,用if…else结构比较好,否则应选择switch结构。
【例6.13】模拟拨打10086服务热线 给10086移动客服中心打电话,如果不是移动电话的用户,则提示“暂时无法提供服务”;如果是移动的用户,则提示“查询话费请拨1,人工服务请拨0”。用户输入1之后,显示话费余额。
使用if…else语句和switch语句模拟此场景,代码如下:
首先,判断用户拨打的是否是10086,只有两种可能,检验的条件少,所以使用if…else语句更为方便。接下来判断用户选择的服务,就要对2~3种甚至更多情况进行检验,由于检验条件比较多,所以使用switch语句比较合适。其中,case语句用来判断用户输入的服务选项,default语句用于在输入数字不符合条件时提示“暂时无法提供服务”。
运行程序,显示效果如上图所示。
编程训练
训练11:猜价格游戏 猜商品的价格,并提示猜的结果偏大还是偏小。本实例中,利用if…else语句实现,然后利用printf函数显示相应的信息。输出结果如下:
请输入猜的价格:
25
您猜小了
训练12:考试成绩等级 要求按照考试成绩的等级输出分数段,其中要使用switch语句来判断分数的情况。分数详细信息如下:
A:90~100分。
B:80~89分。
C:70~79分。
D:60~69分。
F:小于60分。
利用switch语句编写,最终运行结果如下:
请输入要查看的等级:
B
分数段是:80~89
6.7 实践与练习
综合练习1:微信小程序,我该玩哪个 微信小程序由于不需要下载App,深受大家青睐。利用if语句判断输入的数值,输出对应的微信小程序游戏。输出结果如下:
综合练习2:模拟自动售货机 在自动售货机上购买商品时,通常是通过按键选择商品。例如,按键1代表巧克力,按键2代表选择小面包,按键3代表选择可口可乐。利用switch语句模拟实现此场景,运行结果如下:
综合练习3:输出玫瑰花语 女生都喜欢玫瑰花,因为每种玫瑰花都代表不同的含义。例如,红玫瑰代表“我爱你、热恋,希望与你永恒相爱”; 白玫瑰代表“纯洁、谦卑、尊敬,我们的爱情是纯洁的”;粉玫瑰代表“初恋,喜欢你那灿烂的笑容,年轻漂亮”; 蓝玫瑰代表“憨厚、善良”。选择不同的玫瑰,输出对应的花语,运行结果如下:
综合练习4:寻找最大值 设计一个程序,通过键盘输入任意3个整数,输出其中最大的数。运行结果如下:
综合练习5:自助服务 某商店支持自助服务,支付方式有3种,数字1代表网络支付,数字2代表银行卡支付,数字3代表现金支付,顾客可根据输入的数字选择一种支付方式。输出结果如下:
综合练习6:输出美团外卖待支付金额 利用条件运算符输出美团外卖订单。订单金额满15元可免费配送,否则就要加上5元的配送费。运行程序,结果如下:
订单金额小于15元,如下图:
订单金额大于15元,如下图:
综合练习7:空气质量指数 空气质量指数AQI(Air Quality Index)是定量描述空气质量状况的指数,分为6级,对应空气质量的6个类别,其数值越大,说明空气污染状况越严重。表6.1为空气质量等级、指数范围及相应的空气质量状况对应表。
编写程序,输入所在城市的空气质量指数,输出空气质量状况和出行建议,效果如图6.25和图6.26所示。
综合练习8:判断是否为酒后驾车 国家质量监督检验检疫局发布的《车辆驾驶人员血液、呼气酒精含量阈值与检验》中规定:
车辆驾驶人员100ml血液中的酒精含量小于20mg不构成饮酒驾驶行为;大于等于20mg且小于80mg为饮酒驾车;大于等于80mg为醉酒驾车。编写程序,输入血液中的酒精含量,判断是否为酒驾。运行结果如下: