2011-03-08 74 views
3

我写了下面的代码:switch语句和增量操作

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

代码的输出是这样的:

01 
1 

任何人都可以请解释输出的第一行?为什么0和1都被打印?

+0

任何语言的最大设计缺陷:http://programmers.stackexchange.com/questions/55047/what-is-the-greatest-design-flaw-you-have-faced-in-any-programming-language/ 55128#55128'switch'为这种愚蠢的(容易出错的)行为评定了第一位。 – 2011-03-08 10:45:24

回答

18

首先,表达i++递增运算符)的计算结果为0(即使它的i值设定为1)。所以switch里面,case 0:分支选择。

然后,因为你case 0:后无break,程序继续在case 1:标签执行代码。

总结起来,你有:从第一个switch分支0,第二个分支1和另一个1,因为这是最终值i

7

因为您需要在每种情况后添加break,这会阻止执行以下语句。例如。

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

不可否认的是,第二个破发是多余的,但我把它放在那里只是为了一致性

+0

您是否通常不会将'break'缩进以与'case'分支中的语句块对齐?这对我来说很奇怪。 – 2011-03-08 09:49:43

+0

是的,但是格式化代码对于SO来说可能是乏味的。固定。 – dandan78 2011-03-08 09:51:05

2

你需要把着想“的突破;”在每个案件结束时。

0

开关是一种奇怪的构建体。它来自C,Java和C#也采用它,所以它不被认为是完全“非OO”。在其上发生变化是有效的OO的概念,但是通常状态

开关用于基于类型的切换。

特别是编译器通常会创建一个“跳转”表,这意味着它是O(1)调用了哪个代码块,与嵌套的“if”语句不同。您可能有多个值(不包括默认值)跳转到同一点,因此代码块彼此“碰撞”,除非您明确插入“break”语句。

这是它是如何用C完成,并已保留C++。

关于开关中的值,它必须是数值,但不一定是常数。你的情况i++计算结果为0,但i递增1。这是明确的行为,并没有与此序列点没有问题。

+0

这是一个后增量操作符,正确。所以,它在作为它的一部分的表达式中完成它的工作后会增加......所以它就像它打印出0之后,它自身递增,然后转到情况1 – avinash 2011-03-08 11:03:42