一、switch-case语句
1. switch语句中的每个语句段中都使用break语句
switch-case语句的一般形式为:
switch (表达式){
case 常量表达式1:
语句段1;
break;
case 常量表达式2:
语句段2;
break;
...
case 常量表达式n:
语句段n;
break;
default:
语句段n+1;
break;
}
这是switch-case语句的一般用法,即每个case语句后面配一个break语句,其执行流程图如下:
switch语句中,表达式和常量表达式的值一般是整型或者字符型,所有的常量表达式的值都不能相等。每个语句段可以包括一条或多条语句,也可以为空语句。
switch语句中的default可以省略,省略后,当表达式的值与任何一个常量表达式都不行等时,就什么也不执行。
注: 1、switch语句中的常量表达式必须是整型或者字符型,不能为浮点类型,否则编译器会报错。
2、case后的必须为常量表达式,不能为关系表达式,如x>0
,x==3
这样的表达式是不合法的。
3、case后的常量表达式可以为const修饰的常变量,但此时只有C99以后的标准才会支持!
例1:查询自动售货机中商品的价格
假设自动售货机出售4种商品:薯片(crisps)、爆米花(popcorn)、巧克力(chocolate)和可乐(cola),售价分别是每份3.0、2.5、4.0和3.5元。在屏幕上显示以下菜单(编号和选项),用户可以连续查询商品的价格,当查询次数超过5次时,自动退出查询;不到5次时,用户可以选择退出。当用户输入编号1~4,显示相应商品的价格(保留1位小数);输入0,退出查询;输入其他编号,显示价格为0。
[1] Select crisps
[2] Select popcorn
[3] Select chocolate
[4] Select cola
[5] Exit
#include <stdio.h>
int main(void)
{
int choice, i;
double price;
/*以下5行显示菜单*/
printf("[1] Select crisps\n"); /*查询薯片价格*/
printf("[2] Select popcorn\n"); /*查询爆米花价格*/
printf("[3] Select chocolate\n"); /*查询巧克力价格*/
printf("[4] Select cola\n"); /*查询可乐价格*/
printf("[0] Exit\n"); /*退出查询*/
for (i=1; i<=5; i++){
printf("Enter choice:");
scanf("%d", &choice);
/*如果输入0,提前结束for循环*/
if (choice == 0)
break; /*此处用break跳出for循环*/
/*根据输入的编号,将相应的价格赋给price*/
switch (choice){
case 1: price = 3.0; break; /*用break跳出switch语句*/
case 2: price = 2.5; break;
case 3: price = 4.0; break;
case 4: price = 3.5; break;
default: price = 0.0; break;
}
/*输出商品的价格*/
printf("price = %0.1f\n", price);
}
printf("Thanks\n"); /*结束查询,谢谢用户使用*/
return 0;
}
[1] Select crisps
[2] Select popcorn
[3] Select chocolate
[4] Select cola
[0] Exit
Enter choice:3
price = 4.0
Enter choice:2
price = 2.5
Enter choice:8
price = 0.0
Enter choice:0
Thanks
例2:两个数的简单计算器
编写一个简单计算器程序,可根据输入的运算符,对两个整数进行加、减、乘、除和求余运算,请对除数为0的情况做特别处理。要求使用switch语句编写。
#include <stdio.h>
int main(void)
{
int value1, value2;
char op;
printf("Type in an expression:");
scanf("%d%c%d", &value1, &op, &value2);
switch (op) {
case '+':
printf("= %d\n", value1+value2);
break;
case '-':
printf("= %d\n", value1-value2);
break;
case '*':
printf("= %d\n", value1*value2);
break;
case '/':
if (value2 != 0){
printf("= %d\n", value1/value2);
} else { /*对除数为0做特殊处理*/
printf("Divisor can not be 0!\n");
}
break;
case '%':
if (value2 != 0){
printf("= %d\n", value1%value2);
} else { /*对除数为0做特殊处理*/
printf("Divisor can not be 0!\n");
}
break;
default:
printf("Unknown operator\n");
break;
}
return 0;
}
Type in an expression:8%8
= 0
Type in an expression:-3&0
Unknown operator
注意: scanf()输入表达式时,数字和运算符之间不能有空格!想要兼容空格需要对空格做处理。
2. switch语句中某些语句段使用break语句
break语句在switch语句中是可选的,若不使用break,则其一般形式为:
switch (表达式){
case 常量表达式1:语句段1;
case 常量表达式2:语句段2;
...
case 常量表达式n:语句段n;
default: 语句段n+1;
}
其执行流程图是上个流程图里虚框里的内容。执行过程:求解表达式后,如果表达式的值与某个常量表达式的值相等,则执行该常量表达式后的所有语句段,如果表达式的值与任何一个常量表达式的值都不相等,则执行default后的所有语句段。
其中break语句的作用是跳出switch语句,可以在case语句后按需要给其配一个break语句。根据表达式的值执行相应常量表达式后的语句后,switch语句会继续执行以下的所有程序,无论case后面的常量表达式为何值,都会按顺序执行所有的可执行的语句,直到遇到break语句才会跳出switch语句。break语句在循环中的作用也很大。
例:统计字符
输入一个正整数n,再输入n个字符,分别统计出其中空格或回车、数字字符和其他字符的个数。要求使用switch语句编写。
#include <stdio.h>
int main(void)
{
int blank, digit, i, n, other;
char ch;
blank = digit = other = 0; /*置存放统计结果的3个变量的初值为零*/
printf("Enter n:");
scanf("%d", &n);
getchar(); /*读入并舍弃换行符*/
printf("Enter %d characters:", n);
for (i=1; i<=n; i++){
ch = getchar();
/*在switch语句中灵活应用break*/
switch (ch){
case ' ': /*语句段为空,请注意空格符的表示方式*/
case '\n':
blank++; /*两个常量表达式' '和'\n'共用该语句段*/
break; /*跳出switch语句*/
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
digit++; /*10个常量表达式'0'-'9'共用该语句段*/
break; /*跳出switch语句*/
default:
other++; /*累加其他字符*/
break;
}
}
printf("blank = %d, digit = %d, other = %d\n", blank, digit, other);
return 0;
}
Enter n:12
Enter 12 characters:7634
43 &*fo
blank = 2, digit = 6, other = 4
从该例可以看到:switch语句中case后的常量表达式可以为空,这样如果表达式的值与之相匹配,会按照顺序执行下一个语句段,即两个或多个常量表达式可以共用一个语句段。该段程序的常量表达式’ ‘和’\n’共用一个表达式;常量表达式’0’~'9’也是共用一个语句段。灵活使用break语句就可以实现一些特定的需求。
注: 本例中也可以看出,多分支结构switch-case也可以实现,但是有时候if-else语句更有优势。例如case后面就不可以写成case ch>='0' && ch<='9'
这样的形式,而用if语句就可以轻松实现!switch和if语句各有优势。
二、多分支结构
如前文switch-case语句可以实现多分支结构,同样嵌套的if语句也可以实现多分支结构。它的一般形式如下:
if (表达式1)
if (表达式2) 语句1;
else 语句2;
else
if (表达式3) 语句3
else 语句4;
其流程图如下:
if (表达式1)
if (表达式2) 语句1;
else
if (表达式3) 语句2;
else 语句3;
注意:这里尽管格式上第一个else与第一个if对齐,但是第一个else仍然是与第二个if相对应的。一般来说,内嵌的if-else语句最好不要省略大括号,这样结构清晰,直观。因为大括号内的相当于一个语句。所以上式可以改写为:
if (表达式1){
if (表达式2) 语句1;
} else {
if (表达式3) 语句2;
else 语句3;
}
这样可以很明显看出第一个if同第一个else相匹配。结构较清晰。
以前的文章里所讲的级联的else-if语句同样可以实现多分支结构。https://blog.csdn.net/passxgx/article/details/123473026?spm=1001.2014.3001.5501
三、总结
通过上文可以看到,实现多分支结构可以使用if-else语句,或者级联的else-if结构。同样也可以使用switch-case语句,但是switch-case语句仅能是常量表达式,例如表示一些分段函数的情况下,远没有if语句方便简单。switch-case语句的优点是结构清晰,直观,可读性强。如果if-else语句嵌套过多,可读性会大大降低,相对来说级联的else-if语句直观一些,但没有switch-case结构清晰。在设计程序时要根据需要选择合适的语句来实现多分支结构。
参考 C语言程序设计(第4版)/何钦铭,颜晖
例题及课后习题参考程序https://gitee.com/sgxgitee/mooc-c