int main(){ int i=1,b; b=(i++)+(i++); //关键点 printf("this is i %d\n",i); printf("this is b %d\n",b); return 0; } 结果 this is i 3 this is b 3
i 等于 3,并不难想代码中有 2 次++操作。
b 等于 3,可能要难想一点。
b=(i++)+(i++)
先计算表达式在自增
(i++)+(i++)=1+2=3
第一个括号先取值得到 1,在自增。 第二个括号先取值得到 2,在自增。
上面是后缀符号,前缀符号,我还没搞明白。
把b=(i++)+(i++);
改成b=(++i)+(++i);
结果为
this is i 3 this is b 6
我想来想去也不应该等于 6 啊! 正常逻辑应该是等于 5 啊!先自增在计算表达式!
后来我又改成了 b=(++i)+1+(++i);`
结果还是等于 6.
改成了 b=(++i)+2+(++i);` 结果等于 7;这才说的通啊。。。
1 dengshuang OP 环境 ``` debian9.5 64 位 gcc 6.3.0 ``` |
![]() | 2 minami 2018-10-11 15:53:42 +08:00 ![]() 编译器已经很累了,它只想老老实实做优化,不想再和谭浩强玩了,你关心过它的感受吗?没有,你只关心你的 C 语言成绩 ![]() 正经点说,研究这个没啥意义,你可以反编译看看汇编代码是什么样的。 |
![]() | 3 misaka19000 2018-10-11 16:00:14 +08:00 ![]() 第一个: (i++)+(i++) 左边的值为 1,右边的值为 2,1 + 2 = 3 第二个: (++i)+(++i) 我算出来 b 是 5,不知道为什么你算得是 6 |
4 seeker 2018-10-11 16:01:57 +08:00 b=(++i)+(++i) 从结果强行猜编译后可能是这样的: i = i + 1 // 计算 ++i i = i + 1 // 计算又一个 ++ i int x = i // 赋值 1 int y = i // 赋值 2 b = x + y //最终结果 真实情况可以看看汇编咋回事 PS. 没人会这样写代码 |
5 hobochen 2018-10-11 16:03:20 +08:00 via Android ![]() 我觉得 gcc 要提供这样的功能,出现未定义行为自动格式化所有硬盘 |
![]() | 6 xiri 2018-10-11 16:06:22 +08:00 via Android 刚刚运行了一下,我算出来是 b=5 |
7 dengshuang OP @misaka19000 看到你的结果,我就安心了。跟编译器有关 |
![]() | 8 crab 2018-10-11 16:09:02 +08:00 这种看汇编吧,但别写这种和自己过不去的。知道 i++和++i 就行 |
![]() | 9 innoink 2018-10-11 16:10:22 +08:00 via Android sequence point 了解一下 |
![]() | 10 innoink 2018-10-11 16:11:28 +08:00 via Android ![]() 要么不钻牛角尖 要么去学标准做语言律师 要么看汇编面向实际 |
![]() | 11 misaka19000 2018-10-11 16:12:39 +08:00 @xiri #6 为什么你的头像怎么萌(**) |
12 seeker 2018-10-11 16:17:41 +08:00 b=(++i)+(++i) GCC 编译后是这样的,所以是 6,过程跟我猜的差不多,MSVC 和 Clang 编译出来的应该是结果为 5。楼主喜欢钻牛角尖的话可以试试,GCC 让他不要优化。 mov DWORD PTR [rbp-20], edi mov DWORD PTR [rbp-4], 1 add DWORD PTR [rbp-4], 1 add DWORD PTR [rbp-4], 1 mov eax, DWORD PTR [rbp-4] add eax, eax mov DWORD PTR [rbp-8], eax mov eax, DWORD PTR [rbp-8] 我是用这个网站看汇编的: https://godbolt.org/ |
![]() | 13 xiri 2018-10-11 16:26:30 +08:00 via Android |
15 newtype0092 2018-10-11 16:34:46 +08:00 这不叫难题,这叫傻逼问题。。。 |
16 adoui 2018-11-18 16:42:24 +08:00 b = (i++) + (i++); b = 1 + (2); 前面的的括号中 i =1,然后+1,到第二个括号是 i = 2 了,然后 1+2 赋值给 b。++放后面是先用后加。 |