在有多个选择分支条件的情况下,用if 语句难免会繁琐且效率不高,此时便是switch语言的用武之地。
int i=1;
switch(i)
{
case 0:
printf("0");
case 1:
printf("1");
case 2:
printf("2");
default:
printf("default");
}
有些人会认为运行的结果是 2, 但是实际情况是 12default.
这也是初学者常犯的错误。按照常理,switch是选择分支,即满足那个case 执行那个case 块的语句,但是C语言中的switch有它的个性。来看看MSDN 的定义。
You can use the break statement to end processing of a particular case within the switch statement and to branch to the end of the switch statement. Without break,the program continues to the next case, executing the statements until a break or the end of the statement is reached. In some situations, this continuation may be desirable。
意思是,用break 语句 终止 当前的case ,直接到达switch 的末尾,执行完当前case 若有break则跳出switch。
如果没有break, 程序继续流向下一个case ,直到遇到break,或者 到达了switch末尾。
所以如果没有break语句,找到匹配条件的case 后,会从这里继续执行下面的case 直到最后一个case 或default。
明白了这个我们在上面的代码应该这样写。
int i=1;
switch(i)
{
case 0:
printf("0");
break;
case 1:
printf("1");
break;
case 2:
printf("2");
break;
default:
printf("default");
break;
}
这样就会输出 1;
一定要养成良好的习惯,给每一个case 加上break,以免造成疏忽的错误。
但是C语言的这种switch 特性也有它的优点。
比如设置每一个月的天数 Days 可以这样用switch
switch(month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12 :
Days=31;
break;
case 2:
//根据是否是闰年判断。
break;
case 4:
case 6:
case 9:
case 11:
Days=30;
break;
default: break;
}
这样便不用给每个case 都写语句了,case 1 3 5 7 为空,会自动到下一个CASE ,知道case 12 ,执行完跳出。
关于 defaut的位置。
这个问题相信有一大部分人没有考虑过,因为常见的程序中default 都在最后,这要造成了一些人认为default 在最后。
MSDN 的说法:
There can be at most one default statement. The default statement need not come at the end; it can appear anywhere in the body of the switch statement. In fact it is often more efficient if it appears at the beginning of the switch statement. A case or default label can only appear inside a switch statement.
最多有一个default 语句在一个switch 中,default 声明不一定在末尾,它可以出现在switch的任何地方那个,实际上如果default出现在switch 的开头会更有效率。
所以
int i=2;
switch(i)
{
default :break;
case 0:
printf("0");
break;
case 1:
printf("0");
break;
case 2:
printf(“2”);
break;
} 也是合理的。
关于switch()参数值的类型。
参数值类型必须是这几种类型之一:int,long,short ,byte,char.
switch为什么只能用int,short,byte,char,long,因为switch 只能使用 int 类型或者是可以转换为 int类型的参数(char,char 和 int 通过ascii转换)。
C语言没有规定一定是int 类型,但是要求是完整的,因此只能是上面几种了。
关于switch 中case 的个数。
标准的C编译器至少允许一个switch中最多257个case 标签。这是为了允许switch满足一个字符8位的所有情况,总共是2的8次方256,再加上EOF.
而Miscrosoft C 编译器的switch中case 是这样定义的。
MSDN :
Microsoft C does not limit the number of case values in aswitch statement. The number is limited only by the available memory. ANSI C requires at least 257 case labels be allowed in aswitch statement.
它不限制case 的个数。 only limited by available memory.
关于switch 中声明变量初始化的问题。
int i=2;
switch(i)
{
case 1:
break;
case 2:
int sum=5;
sum=sum*i;
printf("%d",sum);
break;
default:
break;
}
运行的结果是什么呢。有人可能认为是 10,然而这样写编译器会报错,在VC6,下 为 error C2361: initialization of 'sum' is skipped by 'default' label
意思是sum变量的初始化被default 跳过 ,没有被初始化。
来看MSDN 的说明:
Note Declarations can appear at the head of the compound statement forming theswitch body, but initializations included in the declarations are not performed. Theswitch statement transfers control directly to an executable statement within the body, bypassing the lines that contain initializations.
声明可以出现在switch 块中复合语句的头部(这是C语言的规则,不允许在语句的中间声明变量,C++可以 ,当然在VC6下可以的通过的,因为它是C/C++的混合编译器),但是包含在声明中的初始化不会被执行。
当写成 int sum; 不报错,运行结果为 -858993460,随机的,因为没有初始化。
解决的方法为给case 下的语句加上{} 号,便可初始化。
int i=2;
switch(i)
{
case 1:
break;
case 2:
{
int sum=5;
sum=sum*i;
printf("%d",sum);
break;
}
default:
break;
}
运行结果为10,已初始化。