4.10 给程序更多选项——switch语句
4.10.1 switch语句的一种应用形式
1.预备知识
switch语句是C语言中用到关键字最多的一个控制语句,也是最难形容的一个,它的一般格式加下:
然而这种形式的switch语句几乎从来不会被使用,除非其中的语句是一个块或复合语句,而且其中需要包含含有关键字case或default的若干标号语句,其形式如下:
其中switch、case、default是这个语句用到关键字。当然,抬杠的说法是case、default都是可选的。
switch语句的执行过程如下。
(1)求整数类型表达式的值;
(2)如果这个值和某个case后面的常量表达式的值相等则执行相应“:”后面的语句,然后依次执行后面的各语句。
(3)如果整数类型表达式的值和任何一个case后面的常量表达式的值都不相等,则执行default:后面的语句,然后依次执行后面的各语句。
这里需要说明一下,对default和各个case并没有次序要求。也就是说,唯一的一个default也可以写在前面或中间。
本书用如图4-5所示的方式表示switch语句的N-S图,其中垂直的虚线表示虚线左面的语句执行完毕后执行虚线右面的语句;垂直的实线左面的语句执行完毕后执行底端实线下面的语句。
图4-5 switch语句的流程图(一)
说明如下。
各个case后面的整数类型常量表达式的值不可以相同。
default:不是必须的而是可选的,也就是说可以没有default:。但如果有,就一定是唯一的。
各个case也不是必须的,但是没有case的switch语句没有什么实际意义。case的个数理论上没有限制。
default:与各case没有顺序要求,default不是必须放在最后的。
关键字case、default所标记的语句,从来不可以单独使用,它们只可以出现在switch语句的语句块中。
2.计算星期几
题目:已知2008年1月1日是星期二,要求输入2008年任意一天的月份和几日,输出这天是星期几(2008年是闰年)。
分析与算法:由于已知2008年的第一天是星期二,第二天就是星期三……由于一个星期是7天,所以这年的第n天是星期几可根据(n+1)%7判断。如果余数为0则为星期天,否则余数是几就是星期几。这样问题的关键就是求输入的日期是这年的第几天。
求输入的日期是这年的第几天可以简单地把这个月份前各个月的天数相加,再加上这天代表这天的日号即可。
程序代码4-10
程序输出:
对于这样的问题,仅仅用一组数据进行测试显然是很不充分的。实际上,至少对每个月开头和结束的日期都应该进行测试。这个工作留给读者自己完成。
练习
程序代码4-10输入正确的时候可以得到正确的结果,但在输入错误日期的情况下(诸如132或133这样不合理的输入)也能输出这天是星期几。这是很荒谬的。请自己编写一程序,能计算正确日期是星期几,且不会计算错误日期是星期几。
4.10.2 switch语句中的break语句
1.break的作用
switch语句更经常与break语句一起使用。break语句可以出现在switch语句的语句块中。switch语句块中的break语句的作用是结束switch语句,使程序开始执行switch语句后面的语句,而不是像前一小节中所叙述的那样继续向下执行switch语句块中的后面的诸条语句。从下面两个例子可以清楚地了解break语句在switch语句中的作用。
可以看出switch语句中的break语句的作用和goto非常类似,不同的是break语句不需要标号而是转到特定的位置——switch语句结束的地方,程序执行到switch中的break语句时,程序直接跳转到switch语句块的}之后继续执行。
当然,是否在某些语句后加break语句完全是根据代码要表达的思想需要而决定的。此外前面第二个例子中printf("x");后面的break语句显然不是必须的,这样纯粹是为了形式上的美观。
2.再算星期几
题目同前小节。
分析与算法:实际上2008年1月的各日与是星期几有个简单的关系,具体如下。
其他各月也有类似的关系,如对二月,这个关系如下。
根据这一点很容易求得2008年任意一天是星期几。
程序代码4-11
代码中的return 1;等语句的作用是结束程序。main()中的return语句都用这样的功能。
尽管这段代码也可以只使用一个switch语句完成,亦即在这个switch语句中同时完成判断输入是否合理或计算这天是星期几,但是良好的编程风格是,每次只做一件事情,而不是同时做几件事情。在编程时应该善于把一件复杂的事情分成若干件简单的事情来完成。
这段代码还演示了几个case语句标号共同标识相同的一条语句或一组语句情况下代码的写法,请注意体会。