鱼C论坛

 找回密码
 立即注册
查看: 3369|回复: 30

大家帮忙看看这道题的答案是多少,++i的问题

[复制链接]
发表于 2014-7-12 22:52:14 | 显示全部楼层 |阅读模式
1鱼币
本帖最后由 风之残月 于 2014-11-10 10:15 编辑
#include <stdio.h>
int main(){
        int s,i = 11;
        s =(++i) + (++i);
        printf("%d,%d\n",s,i);
}
如上代码,在vc++6.0的运行结果是26,13
很郁闷,为什么不是25,13,想不通,求高手点拨...

最佳答案

查看完整内容

想知道原因就要学汇编,看汇编代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-12 22:52:15 From FishC Mobile | 显示全部楼层
paomaliuju 发表于 2014-7-25 10:12
是的,正常写软件的时候,肯定不这么用,但事实是,遇到了这个问题,并且计算机给出了这样的答案,我只是 ...

想知道原因就要学汇编,看汇编代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-12 23:41:24 | 显示全部楼层
各编译器不同,不要纠结哦~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-7-13 00:00:22 | 显示全部楼层
拈花小仙 发表于 2014-7-12 23:41
各编译器不同,不要纠结哦~

难道不同编译器可能执行的结果不一样,那开发出来的软件在不同编译器下,相同源代码,可能运行结果不一致,岂不是存在很大的bug?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-7-13 00:00:54 | 显示全部楼层
拈花小仙 发表于 2014-7-12 23:41
各编译器不同,不要纠结哦~

难道不同编译器可能执行的结果不一样,那开发出来的软件在不同编译器下,相同源代码,可能运行结果不一致,岂不是存在很大的bug?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-13 00:05:34 | 显示全部楼层
paomaliuju 发表于 2014-7-13 00:00
难道不同编译器可能执行的结果不一样,那开发出来的软件在不同编译器下,相同源代码,可能运行结果不一致 ...

为什么那么纠结呢?分成几步就行了,在实际开发中能用到这种吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-7-13 00:21:19 | 显示全部楼层
拈花小仙 发表于 2014-7-13 00:05
为什么那么纠结呢?分成几步就行了,在实际开发中能用到这种吗?

是,如果这样,结果就是对的:
s = ++i;
s1 = s + (++i)
注:上面需要定义一个s1

只是觉得很奇怪,不知道为啥会这样。有这样一个规律:
s = ++i; s结果是12

s = (++i) + (++i);  s结果是26,即12+14
s = (++i) + (++i) + (++i);  s结果是40,即12+13+15
s = (++i) + (++i) + (++i) + (++i);  s结果是55,即12+13+14+16
s = (++i) + (++i) + (++i) + (++i);  s结果是71,即12+13+14+15+17
……
最后一个++i的值比倒数第二个++i的值大2,而不是1。


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-13 00:25:22 | 显示全部楼层
paomaliuju 发表于 2014-7-13 00:21
是,如果这样,结果就是对的:
注:上面需要定义一个s1

{:7_181:}受教了~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-13 00:42:47 | 显示全部楼层
这问题很简单呀,运算符的优先级,先算两个括号内的数,那i就是加了两次,那就是i就是13啦,两个i相加不就是26吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-13 07:50:33 | 显示全部楼层
论坛自己搜索自增
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-13 21:04:11 | 显示全部楼层
看一下反汇编吧
5:        int s, j=11;
00401028   mov         dword ptr [ebp-8],0Bh
6:        s = (++j)+(++j);
0040102F   mov         eax,dword ptr [ebp-8]
00401032   add         eax,1
00401035   mov         dword ptr [ebp-8],eax
00401038   mov         ecx,dword ptr [ebp-8]
0040103B   add         ecx,1
0040103E   mov         dword ptr [ebp-8],ecx
00401041   mov         edx,dword ptr [ebp-8]
00401044   add         edx,dword ptr [ebp-8]
00401047   mov         dword ptr [ebp-4],edx
7:        printf("s=%d\nj=%d\n",s,j);
0040104A   mov         eax,dword ptr [ebp-8]
0040104D   push        eax
0040104E   mov         ecx,dword ptr [ebp-4]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-13 22:15:11 | 显示全部楼层
C++里是先计算完所有的++A,在执行A+A+A+...的,所以,I的值直接做两次++I就是13,然后执行S=I+I=13+13=26其他的语言里有的是S=12+13的,所以作为语言要移植,最好不要这样写。说不定哪天VC摸个版本就变后面这样了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-7-14 13:53:35 | 显示全部楼层
zhoushilei 发表于 2014-7-13 22:15
C++里是先计算完所有的++A,在执行A+A+A+...的,所以,I的值直接做两次++I就是13,然后执行S=I+I=13+13=26 ...

首先,谢谢您的回答!
其实,我也尝试着这么理解,但是,我又测试了“s=(++i) + (++i) + (++i)”,按照这种理解的话,应该是42,但结果却是40,而且“s=(++i) + (++i) + (++i) + (++i)”的结果是55……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-7-14 13:57:17 | 显示全部楼层
1980469235 发表于 2014-7-13 21:04
看一下反汇编吧
5:        int s, j=11;
00401028   mov         dword ptr [ebp-8],0Bh

谢了,还看不懂这东东
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-7-14 14:57:06 | 显示全部楼层
经查证,得出如下结论:
源代码:
#include <stdio.h>
int main(){
        int s,i = 11;
        s =(++i) + (++i);
        printf("%d,%d\n",s,i);
}
为了证实自己的理解,多做了几个测试:victory:
①如果s = (++i) + (++i); 测试结果,s = 26,i = 13;
②如果s = (++i) + (++i) + (++i); 测试结果,s = 40,i = 14;
③如果s = (++i) + (++i) + (++i) + (++i); 测试结果,s = 55,i = 15;
④如果s = (++i) + (++i) + (++i) + (++i) + (++i); 测试结果,s = 71,i = 16;
……
上述结果是经过了怎样的计算过程?

首先,++i是指变量i先自增1之后才参与运算的;其次,需要理解“自增1之后”中“之后”是指什么时间,此编译器中的“之后”是指(i自增1后)在最小表达式的位置参与运算。
下面就结合上面的例子来解释一下:
第①种情况,是两个++i的表达式相加,i初始值是11,第一个++i自增之后i变成了12,但要注意编译器是要在最小表达式的位置才参与运算,在这里,最小表达式是一个加法,即表达式1加上表达式2(这里的表达式1、2均是++i而已),因此,要在第二个++i之后,i的值才参与运算,很明显,第二++i之后,i的值变成了13,所以,最终结果应该是s = 13 + 13 = 26;
第②种情况,同理,s = (++i) + (++i) + (++i);可以看做是前两个++i运算后,再与第三个++i组成最小表达式,前2个++i的和是26(此时i=12),第三个++i,自增之后,i=14,与前面2个++i的和再相加,结果就是40;
第③种情况,同理,最后一个++i自增后,i的值是15,其s = 26 + 14 + 15 = 55;
第④种情况,同理,最后一个++i自增后,i的值是16,其s = 26 + 14 + 15 + 16 = 71;
……
个人看法,欢迎指正!

(什么是最小表达式请参考图片,画的丑:loveliness:)
11.jpg

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-14 21:25:25 | 显示全部楼层
表示用了3年C++,从来没写过++i+(++i)的代码。。。【狂汗:sweat:(反正用不到,让他去吧:loveliness:
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-18 16:49:55 | 显示全部楼层
根据编译器不同结果也不同
出现26是因为编译器先将i自加两次
i=13;后
在执行s = 13+13;
s=26
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-18 17:37:55 | 显示全部楼层
你写成s=(++i)+(i++)
就可以得到你想要的结果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-19 23:48:54 | 显示全部楼层
去学小甲鱼的 《零基础入门汇编》 学了就很清楚了 如果我没记错里面小甲鱼还提到过这题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-7-21 10:41:52 | 显示全部楼层
爆破2014 发表于 2014-7-19 23:48
去学小甲鱼的 《零基础入门汇编》 学了就很清楚了 如果我没记错里面小甲鱼还提到过这题

嗯,好的,会看的,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-24 17:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表