# C 语言里面的 switch 偶遇 i++
- 这是一个 Switch 语句遇上 i++ 的神奇事件,先看代码:
#include <stdio.h> | |
int main() | |
{ | |
int o=10; | |
printf("%d\n", o++); | |
/* Write C code in this online editor and run it. */ | |
int i=11; | |
switch(i){ | |
case 10:i++;printf("%d\n",i);break; | |
case 11:printf("000=%d\n",i);i++;printf("111=%d\n",i); | |
case 12:i++;printf("222=%d\n",i);break; | |
default:i++;printf("333=%d\n",i); | |
} | |
printf("------------------------------------\n"); | |
i=11; | |
switch(i++){ | |
case 10:i++;break; | |
case 11:printf("000=%d\n",i);i++;printf("111=%d\n",i); | |
case 12:i++;printf("222=%d\n",i);break; | |
default:i++;printf("333=%d\n",i); | |
} | |
printf("4===%d\n",i); | |
return 0; | |
} |
- 可以尝试猜测以下输出( )。
- A 11 11
- B 13 14
- C 12 13
- D 13 13
正解是 B
,原因和 printf
函数一样,在遇到 i++
的时候优先获取值。
10 | |
000=11 | |
111=12 | |
222=13 | |
------------------------------------ | |
000=12 | |
111=13 | |
222=14 | |
4===14 |
-
这里解释如下:
- switch 就提前取了 11 值,暂且将这个值命名为 i [^①];
- 之后
i
还是会++
,此时i
等于 12,那么在之后的有关i
运算就是按照 12 往后继续运算; - 问题在于 case 的运算,因 switch 和 case 语句关系,case 其实是对
i
[^①] 做运算,所以会执行 case 11 之后的语句; - 最后由于 case 11 后面没有
break
语句所有往后 case 语句一直执行,直到 case 12 的 break,退出。
-
了解到这个过程,那么很明显
int i=11; | |
switch(i){ | |
case 10:i++;printf("%d\n",i);break; | |
case 11:printf("000=%d\n",i);i++;printf("111=%d\n",i); | |
case 12:i++;printf("222=%d\n",i);break; | |
default:i++;printf("333=%d\n",i); | |
} |
这个里面 switch(i)
没有 i++
,就只有上面 4 步的 1、3、4 步,答案就是 13。
i=11; | |
switch(i++){ | |
case 10:i++;break; | |
case 11:printf("000=%d\n",i);i++;printf("111=%d\n",i); | |
case 12:i++;printf("222=%d\n",i);break; | |
default:i++;printf("333=%d\n",i); | |
} |
这个里面 switch(i++)
有 i++
,就是上面 4 步的 1、2、3、4 步,答案就是 14。
综上所述,一定要明白 switch 就类似对 i
提前取了一个快照,而且这个快照在 switch
之后就销毁,case 后面语句还是按照 i
的值计算。