switch表达式中变量自增自减对标签的影响
本帖最后由 小蒙 于 2017-10-15 14:16 编辑个人理解:switch(i++)是一个完整表达式,完整表达式的结束是一个序列点,所以程序运行到第一个case的时候,i已经变成完成自增,那么,在i初始值是0的情况下,第一个case 0程序是进不去的,这时候i已经变成了1,和case 0不符。
通过调试,switch()确实是序列点,switch运行完后i的值确实递增了,但是同时,程序竟然能进入case 0,但是这时候i的值确实是1,这我就不懂了。{:10_277:}
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <iso646.h>
#include <ctype.h>
int main(void) {
int i = 0;
while (i < 3){
switch(i++){
case 0:
printf("case 0\n");
break;
case 1:
printf("case 1\n");
break;
case 2:
printf("case 2\n");
break;
default:
printf("default\n");
break;
}
}
return 0;
}
//结果如下
case 0
case 1
case 2
没错呀,i++具有滞后性(我自己给的命名),就是说i++后呈现出的 i 的值还是以前的值,但是当下一次遇到 i 了才会显现出自增后的值,swich的时候虽然 i++ 了,但是 i=0,进入后先到case 0,但是到while判断的时候 i = 1,进入后到swich虽然i++,但是还是 i=1,就这样,一直到进入到case 2后,出去到while判断 i = 3,不循环,退出。 swith(i++)相当于两句:
swith(i)
{
...
}
i++; 本帖最后由 小蒙 于 2017-10-15 15:24 编辑
丶忘却的年少o 发表于 2017-10-15 14:51
没错呀,i++具有滞后性(我自己给的命名),就是说i++后呈现出的 i 的值还是以前的值,但是当下一次遇到 i...
https://i.loli.net/2017/10/15/59e30d1ce217e.jpeg
在case0里面,并没有遇到i,但是i的值已经是1了。 丶忘却的年少o 发表于 2017-10-15 14:51
没错呀,i++具有滞后性(我自己给的命名),就是说i++后呈现出的 i 的值还是以前的值,但是当下一次遇到 i...
重新传了图,麻烦看一下。 BngThea 发表于 2017-10-15 15:14
swith(i++)相当于两句:
swith(i)
for(int i = 0; i++<5;)
printf("%d ", i);
return 0;
//结果
1 2 3 4 5
如果switch是这样的话,那这个怎么理解? 小蒙 发表于 2017-10-15 15:28
这个在for循环中相当于for(int i=0;(i<5,i++);) BngThea 发表于 2017-10-15 15:34
这个在for循环中相当于for(int i=0;(i
那switch(i++)也相当于switch(i, i++)? 小蒙 发表于 2017-10-15 15:17
在case0里面,并没有遇到i,但是i的值已经是1了。
是的,你要是在调试中单独看i的值的确是会增加的,但是在程序里你只有在switch中才出现了i,内部是没有的,但是内部判断的是 i 的值,只有在下一次出现 i 的时候才会改变值。我给你个程序,你可以试试看。
#include <stdio.h>
int main(void)
{
int i = 0, j;
j = i++; // i++优先级肯定大于‘=’的吧,肯定是先运行i++再赋值吧
printf("i = %d\nj = %d\n", i, j);
return 0;
} 丶忘却的年少o 发表于 2017-10-15 15:49
是的,你要是在调试中单独看i的值的确是会增加的,但是在程序里你只有在switch中才出现了i,内部是没有的 ...
c primer plus中有一个序列点和副作用的概念,完整表达式的结尾就是一个序列点,在这个点上所有副作用都在进入下一步之前发生,switch()是一个完整表达式,所以括号结尾就是一个序列点,在进入下一步case后,i的值本身的值肯定会增加(副作用),所以调试会发现i的值是1;但是如你所说,如果i++之后不明确出现i的调用,那么程序使用i的值还是旧值,就像j = i++;中j的值比i要小一样,可惜c primer plus中并没有提及这种特殊情况,多谢多谢。 小蒙 发表于 2017-10-15 16:18
c primer plus中有一个序列点和副作用的概念,完整表达式的结尾就是一个序列点,在这个点上所有副作用都 ...
我没看过那本书,我也刚学没多久,但是代码练习做多了,慢慢的就知道了这个东西,而且视频里也有提到。我个人看书有点看不进去,就没怎么看书{:10_262:} 丶忘却的年少o 发表于 2017-10-15 16:22
我没看过那本书,我也刚学没多久,但是代码练习做多了,慢慢的就知道了这个东西,而且视频里也有提到。我 ...
多谢!@ 丶忘却的年少o 发表于 2017-10-15 16:22
我没看过那本书,我也刚学没多久,但是代码练习做多了,慢慢的就知道了这个东西,而且视频里也有提到。我 ...
还有一个关于goto的问题,我就不开帖了。if (a < b) {
goto x;
}
x:
printf("i am x\n");
为什么不管 a < b 成立与否,标号x对应的printf语句都会执行,感觉不符合逻辑啊? 小蒙 发表于 2017-10-15 16:37
还有一个关于goto的问题,我就不开帖了。
为什么不管 a < b 成立与否,标号x对应的printf语句都会执行 ...
你理解错了,如果 if 条件成立会执行 if 里的语句,但是内部语句刚好有是跳到 x 这个标号的语句执行;那么如果 if 不成立就跳过内部语句,执行后面的语句,但是好巧不巧,后面的语句就是 x 这个标号的语句,那么这么看来,不管 if 成立与否都会执行 x 标号的语句了。 丶忘却的年少o 发表于 2017-10-15 17:03
你理解错了,如果 if 条件成立会执行 if 里的语句,但是内部语句刚好有是跳到 x 这个标号的语句执行;那 ...
给我感觉,这种写法应该是只有当程序由goto“跳到”标号x这里,那x后面的printf才会打印。。。 小蒙 发表于 2017-10-15 17:15
给我感觉,这种写法应该是只有当程序由goto“跳到”标号x这里,那x后面的printf才会打印。。。
哈哈,其实不是这样的,就是一个标号,就像调试时候的断点一个意思。goto基本不用,尽量少用,跳来跳去容易出错。而且跳出去回不来,要么就再加一个goto跳回来 丶忘却的年少o 发表于 2017-10-15 19:23
哈哈,其实不是这样的,就是一个标号,就像调试时候的断点一个意思。goto基本不用,尽量少用,跳来跳去容 ...
你好,我开了一个新帖子,有关于文件结束符和被getchar()读取后又放回队列导致无限循环的问题,能否帮忙看一下,谢谢。http://bbs.fishc.com/thread-98080-1-1.html
页:
[1]