C语言switch语句的理解

Posted yuelinghou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言switch语句的理解相关的知识,希望对你有一定的参考价值。

文章目录

一. 基本语法结构

任何具有判定能力的语法结构,都必须具备 判定+分支 功能

在 switch 语法结构中:

  • case 完成的判定功能
  • break 完成的是分支功能
  • default 处理异常情况

举例

根据输入的数字,打印出今天是星期几

int main()

	int day = 0;
	while (1)
	
		printf("Please Enter Your Day# ");
		scanf("%d", &day);
		switch (day) //整型常量、变量或整型表达式
		
		case 1:
			printf("星期一\\n");
			break;
		case 2:
			printf("星期二\\n");
			break;
		case 3:
			printf("星期三\\n");
			break;
		case 4:
			printf("星期四\\n");
			break;
		case 5:
			printf("星期五\\n");
			break;
		case 6:
			printf("星期六\\n");
			break;
		case 7:
			printf("星期天\\n");
			break;
		default:
			printf("input error\\n");
			break;
		
	
	return 0;

编译运行:

二. 几点补充

补充一:关于 default 分支

每次写 switch 语句时,即使程序真的不需要 default 处理,也应该保留以下语句:

default:
	break;

这并非画蛇添足,可以避免让人误以为你忘了 default 处理。而且本来 switch 就适合用在分支较多的情况,最后的 default 也可以方便后续维护代码。

PS:语义上 default 应该放在结尾处,但实际上它可以放在 switch 中的任何地方。

补充二:多条匹配执行同一语句

case 本身是用来进行判断的,当一次判断完成后,其他所有的 case 都将失效(相当于被注释掉),所以当我们想要多条 case 执行同一语句时,可以把这些 case 堆叠在一起。

举例

根据输入的数字,判定今天是周内还是周末

int main()

	int day = 0;
	while (1)
	
		printf("Please Enter Your Day# ");
		scanf("%d", &day);
		switch (day) 
		
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
			printf("周内\\n");
			break;
		case 6:
		case 7:
			printf("周末\\n");
			break;
		default:
			printf("input error\\n");
			break;
		
	
	return 0;

编译运行:

补充三:在 case 语句中定义变量的问题

下面代码在 case 语句中定义了一个 n 变量

int main()

	switch (7)
	
	case 1:
		int n = 10;
		break;
	default:
		break;
	
	return 0;

编译器会报错:

如果我们这样写(在变量定义的地方加上""):

int main()

	switch (7)
	
	case 1:
	int n = 10; 
		break;
	default:
		break;
	
	return 0;

编译器就不会报错,原因如下:

C++编译器考虑了如下的情况:倘若在case 1中定义了一个变量,由于case 1和 default 都在同一个作用域,因此 default 可以调用case 1的变量;如果 default 这样做了,看看会发生什么情况——将会跳过case 1而执行 default,但 default 调用的case 1的变量还没有定义,因此会发生错误!

为了防止这样情况,就需要在case 1中定义变量的部分加上"",以限制变量的作用域(防止被 default 调用),从而防止出错。

假设 default 一定要调用case 1中的变量,那就把这个变量定义成全局变量。

三. 几点建议

建议一:按执行频率排列 case 语句

把最常执行的情况放在前面,而把最不常执行的情况放在后面。这样做有两个好处:

  • 最常执行的代码可能也是调试的时候要单步执行最多的代码。如果放在后面的话,找起来可能会比较困难,而放在前面的话,可以很快找到。
  • 程序执行运行起来,匹配的时候可以较少次的匹配。

细节二:简化每种情况对应的操作

写 case 时,建议使得与每种情况相关的代码尽可能的精炼。case 语句后面的代码越精炼,case 语句的结果就会越清晰。试想,如果case语句后面的代码整个屏幕都放不下,这样的代码谁也很难看得清晰吧。如果某个 case 语句确实需要这么多的代码来执行某个操作,那可以把这些操作写成一个或几个函数,然后在 case 语句后面调用这些函数就ok了。一般来说,case语句后面的代码尽量不要超过20行。

细节三:将 default 字句只用于检查真正的默认情况

有时候,你只剩下了最后一种情况需要处理,于是就决定把这种情况用default 子句来处理。这样也许会让你偷懒少敲几个字符,但是这却很不明智。因为这样将失去 case 语句的标号所提供的自说明功能,而且也丧失了使用 default 子句处理错误情况的能力。所以最好老老实实地把每一种情况都用case 语句来完成,而把真正默认情况的处理交给 default 子句。

C语言及程序设计项目1-26-2&3&5:成绩等级 & 分段函数求值switch语句版 & 个人所得税计算器switch语句版

switch语句常用于解决多分支、分段问题,该语句的关键就在于将具体问题中的分段、分支条件转化为常量constant

首先,一定要理解switch语句是如何执行的:

 

项目1-26-2:成绩等级

 1 /* 成绩等级(switch).cpp: 
 2 问题描述:给出一百分制成绩,要求输出成绩等级’A’,’B’,’C’,’D’,’E’。90分以上为’A’,80-89分为’B’,70-79分为’C’,60-69分为’D’,60分以下为’E’。
 3 */
 4 
 5 #include "stdafx.h"
 6 
 7 int main()
 8 {
 9     int dgrade, dgrade_10;
10 
11     printf("Input the number form of the grade.\\n");
12     scanf_s("%d", &dgrade);
13     
14     //dgrade_10 = dgrade/10;
15 
16         switch (dgrade/10)
17         {
18         case 0:
19         case 1:
20         case 2:
21         case 3:
22         case 4:
23         case 5: printf("grade E"); break;
24 
25         case 6: printf("grade D"); break;
26 
27         case 7: printf("grade C"); break;
28 
29         case 8: printf("grade B"); break;
30 
31         case 9: printf("grade A"); break;
32 
33         case 10: printf("grade A"); break;
34 
35         default:printf("invalid value");break;
36         }
37 
38     return 0;
39 }

 

程序中,利用了整型数据运算的特性(舍去小数部分)每一个分数段通过运算转化为一个特定的常数;

 

项目1-26-3:分段函数求值switch语句版

问题描述

 

通过运算转化的方案:

 1 #include <stdio.h>  
 2 #include <math.h>  
 3 int main ( )  
 4 {  
 5     int x, a;  
 6     double y;  
 7     scanf("%d", &x);  
 8     a = x/2;   //注意是整数相除  
 9     if (a<0)  
10         a=0;    //这样,x<0时,a值也是0  
11     switch(a)  
12     {  
13     case 0: //即x<2时  
14         y=x;  
15         break;  
16     case 1:  
17     case 2://a为1、2,对应x>=2 && x<6时  
18         y=x*x+1;  
19         break;  
20     case 3:  
21     case 4://a为3、4,对应x>=6 && x<10时  
22         y=sqrt(x+1);  
23         break;  
24     default://如果走到这一分支,对应的是x>=10的所有情况  
25         y=1.0/(x+1);  
26     }  
27     printf("%f\\n", y);  
28     return 0;  
29 }  

 

利用逻辑运算的方案(更优):

#include "stdafx.h"
#include <math.h>


int main()
{
    int x, t;
    scanf_s("%d", &x);

    t = (x < 2) + (x < 6) + (x < 10);

    switch (t)
    {
    case 3: printf("%d", x); break;

    case 2: printf("%d", x*x +1); break;

    case 1: printf("%lf", sqrt(x+1)); break;

    case 0: printf("%lf", 1.0/(1+x)); break;

    default:break;
    }

    return 0;
}

 

很显然第二个方案普适性更高,而第一个方案只适合特殊情形(分段较均匀、有规律)

 

项目1-26-5:个人所得税计算器switch语句版

问题描述

 

利用if-else语句转化的方案:

 1 #include <stdio.h>  
 2 int main ( )  
 3 {  
 4     double dSalary,dTax=0,dNetIncome=0; //请欣符合匈牙利命名法的变量名  
 5     double dValue;   //在模板基础上加一个变量,表示超出起征点的收入  
 6     double dRate, dOffset;  //分别表示税率和速算扣除数  
 7     int iStep;       //用于确定交税的“档次”  
 8     printf("请输入您本月的收入总额(元):");  
 9     scanf("%lf", &dSalary);  
10     // 下面求解应缴个人所和税dTax和税后收入dNetIncome  
11     dValue = dSalary - 3500;   //在起征点基础上考虑纳税  
12     if(dValue <= 0.0)  
13         dTax = 0.0;  //不需要交税  
14     else  
15     {  
16         //这一组if语句确定交税的档次  
17         if(dValue <= 1500)  
18             iStep = 1;  
19         else if(dValue <= 4500)  
20             iStep = 2;  
21         else if(dValue <= 9000)  
22             iStep = 3;  
23         else if(dValue <= 35000)  
24             iStep = 4;  
25         else if(dValue <= 55000)  
26             iStep = 5;  
27         else if(dValue <= 80000)  
28             iStep = 6;  
29         else  
30             iStep = 7;  
31   
32   
33         //根据确定的档次,得到税率和速算扣除数  
34         switch(iStep)  
35         {  
36         case 1:  
37             dRate = 0.03, dOffset = 0.0;  
38             break;  
39         case 2:  
40             dRate = 0.1, dOffset = 105.0;  
41             break;  
42         case 3:  
43             dRate = 0.2, dOffset = 555.0;  
44             break;  
45         case 4:  
46             dRate = 0.25, dOffset = 1005.0;  
47             break;  
48         case 5:  
49             dRate = 0.3, dOffset = 2755.0;  
50             break;  
51         case 6:  
52             dRate = 0.35, dOffset = 5505.0;  
53             break;  
54         case 7:  
55             dRate = 0.45, dOffset = 13505.0;  
56         }  
57         dTax = dValue * dRate - dOffset;  //计算所得税,体会将“确定参数”与“计算”分开的好处:思路更明晰,不易在计算公式上犯大错  
58     }  
59     dNetIncome = dSalary-dTax;        //计算税后收入  
60     printf("您本月应缴个人所和税 %.2lf 元,税后收入是 %.2lf 元。\\n", dTax, dNetIncome);  
61     printf("依法纳税,共享繁荣。谢谢使用!\\n");  
62     return 0;  
63 }  

 

利用逻辑运算的方案:

 1 #include "stdafx.h"
 2 
 3 
 4 int main()
 5 {
 6     double dSalary, dTax = 0, dNetIncome = 0;
 7     printf("请输入您本月的收入总额(元):");
 8     scanf_s("%lf", &dSalary);
 9 
10     double dover, tax_rate, quick_deduction;
11     int x;
12 
13     dover = (dSalary - 3500)/100;
14     
15     x = (dover < 15) + (dover < 45) + (dover < 90) + (dover < 350) + (dover < 550) + (dover < 800);
16 
17         if (dSalary <= 3500)
18         {
19             printf("您本月应缴个人所和税 0 元。\\n");
20             printf("依法纳税,共享繁荣。谢谢使用!\\n");
21             return 0;
22         }
23         else
24         {
25             switch (x)
26             {
27             case 6: tax_rate = 0.03, quick_deduction = 0; break;
28 
29             case 5: tax_rate = 0.1, quick_deduction = 105; break;
30 
31             case 4: tax_rate = 0.2, quick_deduction = 555; break;
32 
33             case 3: tax_rate = 0.25, quick_deduction = 1005; break;
34 
35             case 2: tax_rate = 0.3, quick_deduction = 2755; break;
36 
37             case 1: tax_rate = 0.35, quick_deduction = 5505; break;
38 
39             case 0: tax_rate = 0.45, quick_deduction = 13505; break;
40 
41             default:
42                 break;
43             }
44 
45             dTax = (dSalary - 3500) * tax_rate - quick_deduction;
46             dNetIncome = dSalary - dTax;
47 
48             printf("您本月应缴个人所和税 %.2lf 元,税后收入是 %.2lf 元。\\n", dTax, dNetIncome);
49             printf("依法纳税,共享繁荣。谢谢使用!\\n");
50         }
51 
52     return 0;
53 }

 

利用if-else 语句转化更为通用,但是要说cleanness,还是逻辑运算转化的方案最优。

 

 

 

 

=

以上是关于C语言switch语句的理解的主要内容,如果未能解决你的问题,请参考以下文章

C语言switch语句的理解

关于C语言switch语句问题

c语言中switch可用啥语句替换

C语言switch语句问题(初学)

C语言中switch语句用法(做题)!谢谢!

求教c语言中switch 语句的详细用法