c 自增的难题,想不出头绪。

2018-10-11 15:45:53 +08:00
 dengshuang
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;这才说的通啊。。。

3355 次点击
所在节点    编程
16 条回复
dengshuang
2018-10-11 15:46:28 +08:00
环境
```
debian9.5 64 位
gcc 6.3.0
```
minami
2018-10-11 15:53:42 +08:00
编译器已经很累了,它只想老老实实做优化,不想再和谭浩强玩了,你关心过它的感受吗?没有,你只关心你的 C 语言成绩
正经点说,研究这个没啥意义,你可以反编译看看汇编代码是什么样的。
misaka19000
2018-10-11 16:00:14 +08:00
第一个:
(i++)+(i++)
左边的值为 1,右边的值为 2,1 + 2 = 3
第二个:
(++i)+(++i)
我算出来 b 是 5,不知道为什么你算得是 6
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. 没人会这样写代码
hobochen
2018-10-11 16:03:20 +08:00
我觉得 gcc 要提供这样的功能,出现未定义行为自动格式化所有硬盘
xiri
2018-10-11 16:06:22 +08:00
刚刚运行了一下,我算出来是 b=5
dengshuang
2018-10-11 16:07:51 +08:00
@misaka19000 看到你的结果,我就安心了。跟编译器有关
crab
2018-10-11 16:09:02 +08:00
这种看汇编吧,但别写这种和自己过不去的。知道 i++和++i 就行
innoink
2018-10-11 16:10:22 +08:00
sequence point 了解一下
innoink
2018-10-11 16:11:28 +08:00
要么不钻牛角尖
要么去学标准做语言律师
要么看汇编面向实际
misaka19000
2018-10-11 16:12:39 +08:00
@xiri #6 为什么你的头像怎么萌(*╹▽╹*)
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/
xiri
2018-10-11 16:26:30 +08:00
@misaka19000 #11 你的头像也很萌啊

顺便补充一下我 #6 计算结果的环境:clang 7.0.0 (不在电脑旁,在手机上的 Termux 里算的)
innoink
2018-10-11 16:29:14 +08:00
@seeker sequence point 和优化并没有什么关系,这就是个 UB
newtype0092
2018-10-11 16:34:46 +08:00
这不叫难题,这叫傻逼问题。。。
adoui
2018-11-18 16:42:24 +08:00
b = (i++) + (i++);
b = 1 + (2);
前面的的括号中 i =1,然后+1,到第二个括号是 i = 2 了,然后 1+2 赋值给 b。++放后面是先用后加。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/496744

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX