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 1
编译器已经很累了,它只想老老实实做优化,不想再和谭浩强玩了,你关心过它的感受吗?没有,你只关心你的 C 语言成绩
正经点说,研究这个没啥意义,你可以反编译看看汇编代码是什么样的。 |
3
misaka19000 2018-10-11 16:00:14 +08:00 1
第一个:
(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 6
我觉得 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 1
要么不钻牛角尖
要么去学标准做语言律师 要么看汇编面向实际 |
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。++放后面是先用后加。 |