switch-case语句
背景
对switch语句一个整体的记录。
基本用法
switch语句可以从多个选项中选择。
选项用一组固定的整数或枚举值标识,根据给定整数或枚举常量的值确定选择哪个选项。
示例:
1 | 顾客买彩票,中奖号码:147是一等奖,387是二等奖,29,78就是三等奖。可以这么编写 |
注意
只能对整形值(int、long、unsigned short等)、字符值(char等)和枚举类型值使用switch语句。
从技术角度看,也允许对布尔值使用switch语句,但是这种情况下,其实应该使用if/else语句。
每个case值都必须是唯一的,但不必按一定的顺序。
任何两个case值都不能相同的原因是,如果输入某个指定值,编译器就无法确定应执行哪些语句。
但是case值不同,并不表示必须执行不同的操作。
几个case值可以共享相同的操作。
case值必须是整数常量表达式,即编译器可以在编译时计算的表达式,所以常常是字面量或用字面量初始化的const变量。
一般情况下,case标签后面可以有许多语句,且不需要把它们括在花括号中。
default标签标识默认的case。如果选择表达式不对应任何一个case值,就执行默认case后面的语句。
对于default标签,并不是必须把它作为最后一个标签。
常常把它放在最后,但是原则上,default标签可以放到普通case标签之间的任何位置。
并不一定要有default标签,如果没有指定,且没有选中任何case值,switch语句就什么也不做。
从逻辑上看,每一个case语句后面的break语句是必需的,它在case语句执行后跳出switch语句。
如果省略case后面的break语句,就将执行该case后的所有语句。
注意在最后一个case后面(通常是default)不需要break语句,因为此时程序将退出switch语句。但是加上break语句是一个很好的编程习惯,因为这可以避免以后由于添加另一个case而导致的问题。
break语句并不是使控制权移除switch语句的唯一方式。
如果case标签后的代码包含return语句,则控制权不仅立即离开switch语句,还将离开包含switch语句的函数。
贯穿
很多时候,确实break语句是疏忽大意的表现,说明存在bug。
但是,贯穿并不一定总是意味着错误。有时候,故意写一个利用贯穿行为是switch语句会很有用。
示例如下:
1 | 顾客买彩票,中奖号码:147是一等奖,387是二等奖,29,78,929就是三等奖,而赢得三等奖的特殊号码929可以获得额外的神秘奖励。 |
对于这种代码,令人烦恼的地方是,尽管在这里贯穿并不是错误,但是编译器可能还是会发出贯穿警告。
而作为有自尊心的程序员,我们希望编译的程序里没有任何警告。
对于这种情况,一种方法是重写代码,加上赢得三等奖的输出语句。但是一般来说,我们应该避免重复代码。
那么,还有什么办法呢?
C++17中添加了一个新的语言功能,可告诉编译器和阅读的人,我们在某个地方故意使用了贯穿行为:
在原本会编写break语句的地方,添加一个[[fallthrough]]语句:
1 | …… |
对于空的case,例如对应29号的case,也可以使用[[fallthrough]],但并不是必须这么做。对于这种情况,编译器本来就不会发出警告。