首页
社区
课程
招聘
[求助]问个简单的C++问题,有点迷糊
发表于: 2008-9-16 14:26 3692

[求助]问个简单的C++问题,有点迷糊

2008-9-16 14:26
3692
有个看似很简单的C++问题,但是,真的迷糊了,可能是基础学的不好吧,希望有人能帮我解释一下,谢谢了.
问题是这样的,这么一个C++程序:

#include<stdlib.h>
#include<iostream.h>
int main()
{
  int a(5),b(0);
  b=++a *--a;
  cout<<b<<endl;
system("Pause");
return 0;
}

看上去真的很简单,也很基础,答案是25
当时用这么个方法去解释:
++和--是单目运算符,*是双目运算符,于是先++a后为6,再--a后为5,结果就是5*5=25.
用OD反汇编一下,看反汇编代码:

00401058   .  C745 FC 05000000   mov dword ptr ss:[ebp-4],5     //[ebp-4]=5
0040105F   .  C745 F8 00000000   mov dword ptr ss:[ebp-8],0     //[ebp-8]=0
00401066   .  8B45 FC            mov eax,dword ptr ss:[ebp-4]         //eax=[ebp-4]=5
00401069   .  83C0 01            add eax,1                                        //eax=eax+1=6;也就是++a
0040106C   .  8945 FC            mov dword ptr ss:[ebp-4],eax        //把结果还给[ebp-4]=6
0040106F   .  8B4D FC            mov ecx,dword ptr ss:[ebp-4]       //ecx=[ebp-4]=6
00401072   .  83E9 01            sub ecx,1                                       //ecx=ecx-1=5;也就是--a
00401075   .  894D FC            mov dword ptr ss:[ebp-4],ecx      //再把结果还给[ebp-4]
00401078   .  8B55 FC            mov edx,dword ptr ss:[ebp-4]    //edx=[ebp-4]=5
0040107B   .  0FAF55 FC          imul edx,dword ptr ss:[ebp-4]   //edx=edx*[ebp-4]=5*5
0040107F   .  8955 F8            mov dword ptr ss:[ebp-8],edx    //把edx的值给[ebp-8]
00401082   .  68 0F104000        push 1.0040100F

证实了上面的结论,答案的确是5*5=25

不过,稍微再变下形,又觉得上面的解释有点不清楚了:

这么改:

#include<stdlib.h>
#include<iostream.h>
int main()
{
  int a(5),b(0);
  b=++a *--a*++a;
  cout<<b<<endl;
system("Pause");
return 0;
}

这个改后,再用反汇编代码看了下:

00401058   .  C745 FC 05000000   mov dword ptr ss:[ebp-4],5
0040105F   .  C745 F8 00000000   mov dword ptr ss:[ebp-8],0
00401066   .  8B45 FC            mov eax,dword ptr ss:[ebp-4]
00401069   .  83C0 01            add eax,1
0040106C   .  8945 FC            mov dword ptr ss:[ebp-4],eax
0040106F   .  8B4D FC            mov ecx,dword ptr ss:[ebp-4]
00401072   .  83E9 01            sub ecx,1
00401075   .  894D FC            mov dword ptr ss:[ebp-4],ecx
00401078   .  8B55 FC            mov edx,dword ptr ss:[ebp-4]
0040107B   .  0FAF55 FC          imul edx,dword ptr ss:[ebp-4]
0040107F   .  8B45 FC            mov eax,dword ptr ss:[ebp-4]
00401082   .  83C0 01            add eax,1
00401085   .  8945 FC            mov dword ptr ss:[ebp-4],eax
00401088   .  0FAF55 FC          imul edx,dword ptr ss:[ebp-4]
0040108C   .  8955 F8            mov dword ptr ss:[ebp-8],edx
0040108F   .  68 0F104000        push 1.0040100F
00401094   .  8B4D F8            mov ecx,dword ptr ss:[ebp-8]
00401097   .  51                 push ecx                                    
00401098   .  B9 88004300        mov ecx,1.00430088                           

这时候,发现,计算机是先做++a*--a这个乘法,接着再++a,然后再相乘,结果变为了
5*5*6=150

但按照优先级,不是先应该++a,接着--a,再++a么?
也就是6------5-------6,结果是6*6*6=216么?
实在迷糊,望有人给解释下,谢谢了.

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 109
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这是VC++编译器存在歧义性,对应形如:i++ + i++ + i++;的语句由于中间的+,-,*,/预算法的优先级都地于++或--,因此编译器遇到这个式子时候先对变量i进行++预算,但是运算符+,-,*,/,这边也是一个++或--。所以编译器就继续对变量i进行++或者--操作,然后在完成我们的+,-,*,/操作。比如:y=++x+ ++x; y=0;x=2;VC++/C中编译器编译时会这样的:temp1=x;temp1=temp1+1;temp1=temp1+1;y=temp1+temp1;因为在我们运算符+,-,*,/都要比中间的++要低,编译器不会识别。他只按照优先级顺序进行操作。
在VC++/C中编译器并没有对这种运算作出限制,所以存在二意性。有的vc++/c的书上有解释,外国人写的会解释的很详细,关于vc++/c的编译器特性也要了解一点。
在java中就不会存在了,java对这种式子做了限制。
                                           小弟拜会,有不到之处请高手改过
2008-9-16 15:28
0
雪    币: 63
活跃值: (17)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
没有意义
不要研究这个问题
2008-9-16 15:28
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
嗯~~~ 这个是编译器决定的~ 所以研究没有意义
2008-9-16 19:46
0
雪    币: 229
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
看了一下C++编程思想,里面说觉得这些问题很无聊的,那个先算那个后算用括号就能解决了 写到那么一堆没一点意思。
2008-9-16 22:02
0
游客
登录 | 注册 方可回帖
返回
//