我们来看一道基础题q=(++j)+(++j)+(++j)

beyound 2006-11-22 04:58:01
原题是这样的:
int main(int argc, char* argv[])
{
int i=5,j=5,p,q;
p=(i++)+(i++)+(i++);
q=(++j)+(++j)+(++j);
printf("%d,%d,%d,%d",p,q,i,j);
getchar();
return 0;
}
在VC6环境下DEBUG编译后显示结果15,22,8,8而Release编译后显示结果15,24,8,8而朋友在linux下cc -o test test.c后运行显示的结果也是15,22,8,8而VS.NET2005编译后debug和release的结果都是15,24,8,8,为什么会有这样的差异呢?p、i、j的值没有差异,我单独把q的运算反汇编结果分析了一下
.net下反汇编
int i=5,j=5,p,q;
0041342E mov dword ptr [i],5
00413435 mov dword ptr [j],5
q=(++j)+(++j)+(++j);
00413463 mov eax,dword ptr [j]
00413466 add eax,1 //++j
00413469 mov dword ptr [j],eax
0041346C mov ecx,dword ptr [j]
0041346F add ecx,1 //++j
00413472 mov dword ptr [j],ecx
00413475 mov edx,dword ptr [j]
00413478 add edx,1 //++j
0041347B mov dword ptr [j],edx
0041347E mov eax,dword ptr [j]
00413481 add eax,dword ptr [j] //8+8
00413484 add eax,dword ptr [j] //16+8=24
00413487 mov dword ptr [q],eax //q=24
VC6 DEBUG反汇编
8: int i=5,j=5,p,q;
0040D6F8 mov dword ptr [ebp-4],5
0040D6FF mov dword ptr [ebp-8],5
10: q=(++j)+(++j)+(++j);
0040D72D mov ecx,dword ptr [ebp-8]
0040D730 add ecx,1
0040D733 mov dword ptr [ebp-8],ecx
0040D736 mov edx,dword ptr [ebp-8]
0040D739 add edx,1
0040D73C mov dword ptr [ebp-8],edx
0040D73F mov eax,dword ptr [ebp-8]
0040D742 add eax,dword ptr [ebp-8]//这里没有++j而是先做了前两个操作数的和eax=14
0040D745 mov ecx,dword ptr [ebp-8]//这时候dword ptr [ebp-8]=7
0040D748 add ecx,1 //做了++j这时候ecx=8
0040D74B mov dword ptr [ebp-8],ecx//j=8了
0040D74E add eax,dword ptr [ebp-8]//又做了14+8
0040D751 mov dword ptr [ebp-10h],eax //结果是q=22

我们看到其中的差异发生在.net的代码都是++j三次做完之后统一对三个操作数做了两次+运算,这样3个数的和是24,而VC6的debug是做了两次++j之后做的前两个操作数的+运算,然后又做的++j,然后再做的第二次加法,不知道小弟解释的是否清楚。可是为什么会有这样的差异?请各位牛人帮忙解释一下。debug的编译器时候还靠得住?

...全文
765 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
handsomerun 2006-11-23
  • 打赏
  • 举报
回复
恩,我也认为,不同的编译器,可能导致不同的结果~~~

所以还是要试一下才能知道
Woodman007 2006-11-23
  • 打赏
  • 举报
回复
这种题目 = 垃圾

标准没有明确这种情况,所以,不同的编译器有不同的解读,有不同的优化措施,结果不同也就不奇怪了。实际中是不允许有这种代码的。

请LZ看一下:

http://community.csdn.net/Expert/topic/5050/5050739.xml?temp=.6811487

我把其中一些发言复制过来:


无准确答案。
“cout<<(i++)+(++i)<<endl;”类似的语句中,i++和++i哪个先执行,各种编译器实现可能都不相同,导致结果也不同。

这种写法大概只有在那种故意刁难学生的考试卷子中出现,自己便程序的话,我想是没有人愿意跟自己过不去的。


谁敢在商用软件里写这样的代码,肯定要被领导拉出去砍了。
++/--运算符一直是混乱之源。
在同一行对同一变量有多个++/--操作,基本上一定会导致“未定义”后果。
这是写在C98标准第5章开头的第4条的。


不要研究这种代码啦。根据编译器决定结果。毫无意义。

不同的编译器会有不同的实现,在实际应用中这样的程序是没有意义的。

如果还想老板发你工资 就不要这么玩了 写程序不是玩技巧

这种问题只有在考试中出现,项目中一般不会


靠,谁要是问这种问题,或者让你写这样的代码,一脚踹死他。
记忆中只有软考才喜欢揪出这种没营养没文化的问题。
连什么是标准都不知道却跑出来出考题,害人害己。
软考的编程风格怎一个垃圾了得。



解答依赖于编译器,以及编译开关的设置

编译器不同,结果不同

就算是同一个编译器,Debug版本 与 Release版本的结果也有可能不同

就算是同一个编译器并且同是Debug版本(或者同是Release版本),只要是编译开关的设置不同,所得的结果也不同。

写这种代码纯粹是跟自己过不去,想要刨根问底的话看汇编代码就可以了,平常就没必要研究这种无聊加三级的问题了。

做鸡真好吃 2006-11-23
  • 打赏
  • 举报
回复
mark~
zhanghaif 2006-11-23
  • 打赏
  • 举报
回复
估计面试的时候招聘单位所期待的结果就是:
15,24,8,8
VC6采用的老的C++标准,vc.net 2005采用的是新的C++标准。可能是这个差别导致了两者在编译时产生差别。
xundeng 2006-11-23
  • 打赏
  • 举报
回复
不要老玩这种没有意思的东西
一分之千 2006-11-22
  • 打赏
  • 举报
回复
如果编程天天都写这种程序,过了一个月所有的程序员都得进疯人院!!!!!
laolaoliu2002 2006-11-22
  • 打赏
  • 举报
回复
这种问题有实际意义吗?根本就不能叫基础题目。
yzcurry 2006-11-22
  • 打赏
  • 举报
回复
没实用价值的东西就不要研究了
有意思吗?
bobob 2006-11-22
  • 打赏
  • 举报
回复
如果是面试题,直接走人

在写代码的时候,最好把优先级顺序忘掉
nextday 2006-11-22
  • 打赏
  • 举报
回复
如果这是面试题应该怎么办?
nextday 2006-11-22
  • 打赏
  • 举报
回复
按照我们学的C语方书上的说法结果应该是15,24,8,8 怎么实际编译就一样呢?想不明白。
thisisll 2006-11-22
  • 打赏
  • 举报
回复
崩了~~
liuguangzhou 2006-11-22
  • 打赏
  • 举报
回复
最看不惯面试的时候问这种问题。
要真的是在工作中写这种代码,不被头骂死才怪。
Elysium 2006-11-22
  • 打赏
  • 举报
回复
出这种题的人都是SB,美其名曰考优先级
王国凡 2006-11-22
  • 打赏
  • 举报
回复
赞成下面的结果:
15,24,8,8
nextday 2006-11-22
  • 打赏
  • 举报
回复
而在debug下q=(++j)+((++j)+(++j))的结果是24
nextday 2006-11-22
  • 打赏
  • 举报
回复
即使是q=((++j)+(++j))+(++j);release的结果也是24
bobob 2006-11-22
  • 打赏
  • 举报
回复
研究这种问题纯粹是浪费时间
beyound 2006-11-22
  • 打赏
  • 举报
回复
到底应该遵从哪种优先级呢?
aa3000 2006-11-22
  • 打赏
  • 举报
回复
编译器优化所致,哎,根本不是基础题,一种玩人的题目。

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧