Switch语句和递增运算符

3
我写了以下代码:

我写了以下代码:

int i = 0;  
switch(i++)  
{
   case 0:  
     cout << 0;  
   case 1:  
     cout << 1;
}  
cout << "\n" << i;  

代码的输出结果如下所示:
01  
1

有人能解释一下输出的第一行吗?为什么0和1都被打印出来了?

任何编程语言中最大的设计缺陷:http://programmers.stackexchange.com/questions/55047/what-is-the-greatest-design-flaw-you-have-faced-in-any-programming-language/55128#55128 switch 由于其愚蠢(且容易出错)的行为而被评为第一位。 - Matthieu M.
4个回答

18

首先,表达式i++后增运算符)的值为0(尽管它将i的值设置为1)。因此,在switch语句中选择了case 0: 分支。

然后,由于在case 0:后面没有break语句,程序将继续执行case 1:标签中的代码。

综上所述,你得到了:来自第一个switch分支的0,来自第二个分支的1,以及因为这是i的最终值,另外一个1。


7

因为您需要在每个case之后添加一个break,这样可以防止执行以下语句。例如:

switch(i++)  
{
   case 0:  
     cout<<0;  
     break;
   case 1:  
     cout<<1;
     break;
}  

承认地说,第二个换行符是多余的,但我为了保持一致性而将其添加在那里。

你通常不会将 break 缩进以与 case 分支中的语句块对齐吗?这看起来对我来说很奇怪。 - Cody Gray
是的,但在SO上格式化代码可能有点繁琐。已修复。 - dandan78

2
在每个case的结尾处加上"break;"。

0

switch是一种奇怪的结构。它来自于C语言,Java和C#也采用了它,因此它不被认为是完全“非面向对象”的。

基于状态变化的switch是一个有效的面向对象概念,但通常用于基于类型的切换。

特别是编译器通常会创建一个“跳转”表,这意味着调用哪个代码块是O(1)的,而不像嵌套的“if”语句那样。您可能有多个值(不包括默认值)跳转到同一点,因此代码块“相互运行”,除非您显式插入“break”语句。

这就是C语言中的做法,并已保留给C++。

关于switch中的值,它必须是数值,但不必是常量。在您的情况下,i++计算结果为0,但将i增加到1。这是明确定义的行为,在这里没有序列点的问题。


它是一个后增运算符,对吧。所以,在它作为表达式的一部分执行完毕后,它会被递增...那么它是不是在打印了0之后,就会自增然后进入case 1呢? - AvinashK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接