p=(i++)+(i++)+(i++); q=(++j)+(++j)+(++j);
voidmain(){inti=5,j=5,p,q;p=(i++)+(i++)+(i++);q=(++j)+(++j)+(++j);printf(\"%d,%d,%d,%...
void main(){
int i=5,j=5,p,q;
p=(i++)+(i++)+(i++);
q=(++j)+(++j)+(++j);
printf(\"%d,%d,%d,%d\",p,q,i,j);
}
什么p=15??而q=22 展开
int i=5,j=5,p,q;
p=(i++)+(i++)+(i++);
q=(++j)+(++j)+(++j);
printf(\"%d,%d,%d,%d\",p,q,i,j);
}
什么p=15??而q=22 展开
4个回答
展开全部
这是不好的用法,属于Unspecified Behavior
operator+的两个参数参与运算时,对left operand和right operand的求值顺序,标准没有进行严格定义,所以最终结果取决于相关编译器实现,因而在不同环境下会出现不同的结果
至于你说的那个三个i相加后再自增三次这种说法,只是为了迎合这一结果而生硬的凑出来的解释,事实上这个表达式用clang编译器编译的结果就不是15
跑去又测试了一下,GCC环境下输出为15,22,8,8,VS环境下输出为15,24,8,8,已经印证了这一用法在不同环境下的不确定性,通过分析反汇编可以分析一下gcc和vs采用的不同策略
首先看GCC所生成的汇编
00401326movl $0x5,0x20(%esp)
0040132Emovl $0x5,0x24(%esp
这一部分是p=(i++)+(i++)+(i++);
00401336mov 0x20(%esp),%eax
0040133Aadd %eax,%eax
0040133Cadd 0x20(%esp),%eax
00401340mov %eax,0x28(%esp)
00401344incl 0x20(%esp)
00401348incl 0x20(%esp)
0040134Cincl 0x20(%esp)
可以看出确实是先相加三次再自增三次
这部分是q=(++j)+(++j)+(++j);
00401350incl 0x24(%esp)
00401354incl 0x24(%esp)
00401358mov 0x24(%esp),%eax
0040135Cadd %eax,%eax
0040135Eincl 0x24(%esp)
00401362add 0x24(%esp),%eax
可以看出其运算策略是先自增两次,进行一次累加,再自增一次,随后再累加一次
再来看VS生成的汇编
00FE13EE mov dword ptr [i],5
00FE13F5 mov dword ptr [j],5
p=(i++)+(i++)+(i++);
00FE13FC mov eax,dword ptr [i]
00FE13FF add eax,dword ptr [i]
00FE1402 add eax,dword ptr [i]
00FE1405 mov dword ptr [p],eax
00FE1408 mov ecx,dword ptr [i]
00FE140B add ecx,1
00FE140E mov dword ptr [i],ecx
00FE1411 mov edx,dword ptr [i]
00FE1414 add edx,1
00FE1417 mov dword ptr [i],edx
00FE141A mov eax,dword ptr [i]
00FE141D add eax,1
00FE1420 mov dword ptr [i],eax
这一部分运算策略和GCC一致
q=(++j)+(++j)+(++j);
00FE1423 mov eax,dword ptr [j]
00FE1426 add eax,1
00FE1429 mov dword ptr [j],eax
00FE142C mov ecx,dword ptr [j]
00FE142F add ecx,1
00FE1432 mov dword ptr [j],ecx
00FE1435 mov edx,dword ptr [j]
00FE1438 add edx,1
00FE143B mov dword ptr [j],edx
00FE143E mov eax,dword ptr [j]
00FE1441 add eax,dword ptr [j]
00FE1444 add eax,dword ptr [j]
00FE1447 mov dword ptr [q],eax
这一部分却是先自增三次,再进行两次累加,于是就产生了和GCC不相同的运算结果
通过汇编只是说明一下,这种用法在不同的编译环境下无法预知其结果,所以应该避免这种用法,也不要试图在未知环境中预测这种用法的行为
operator+的两个参数参与运算时,对left operand和right operand的求值顺序,标准没有进行严格定义,所以最终结果取决于相关编译器实现,因而在不同环境下会出现不同的结果
至于你说的那个三个i相加后再自增三次这种说法,只是为了迎合这一结果而生硬的凑出来的解释,事实上这个表达式用clang编译器编译的结果就不是15
跑去又测试了一下,GCC环境下输出为15,22,8,8,VS环境下输出为15,24,8,8,已经印证了这一用法在不同环境下的不确定性,通过分析反汇编可以分析一下gcc和vs采用的不同策略
首先看GCC所生成的汇编
00401326movl $0x5,0x20(%esp)
0040132Emovl $0x5,0x24(%esp
这一部分是p=(i++)+(i++)+(i++);
00401336mov 0x20(%esp),%eax
0040133Aadd %eax,%eax
0040133Cadd 0x20(%esp),%eax
00401340mov %eax,0x28(%esp)
00401344incl 0x20(%esp)
00401348incl 0x20(%esp)
0040134Cincl 0x20(%esp)
可以看出确实是先相加三次再自增三次
这部分是q=(++j)+(++j)+(++j);
00401350incl 0x24(%esp)
00401354incl 0x24(%esp)
00401358mov 0x24(%esp),%eax
0040135Cadd %eax,%eax
0040135Eincl 0x24(%esp)
00401362add 0x24(%esp),%eax
可以看出其运算策略是先自增两次,进行一次累加,再自增一次,随后再累加一次
再来看VS生成的汇编
00FE13EE mov dword ptr [i],5
00FE13F5 mov dword ptr [j],5
p=(i++)+(i++)+(i++);
00FE13FC mov eax,dword ptr [i]
00FE13FF add eax,dword ptr [i]
00FE1402 add eax,dword ptr [i]
00FE1405 mov dword ptr [p],eax
00FE1408 mov ecx,dword ptr [i]
00FE140B add ecx,1
00FE140E mov dword ptr [i],ecx
00FE1411 mov edx,dword ptr [i]
00FE1414 add edx,1
00FE1417 mov dword ptr [i],edx
00FE141A mov eax,dword ptr [i]
00FE141D add eax,1
00FE1420 mov dword ptr [i],eax
这一部分运算策略和GCC一致
q=(++j)+(++j)+(++j);
00FE1423 mov eax,dword ptr [j]
00FE1426 add eax,1
00FE1429 mov dword ptr [j],eax
00FE142C mov ecx,dword ptr [j]
00FE142F add ecx,1
00FE1432 mov dword ptr [j],ecx
00FE1435 mov edx,dword ptr [j]
00FE1438 add edx,1
00FE143B mov dword ptr [j],edx
00FE143E mov eax,dword ptr [j]
00FE1441 add eax,dword ptr [j]
00FE1444 add eax,dword ptr [j]
00FE1447 mov dword ptr [q],eax
这一部分却是先自增三次,再进行两次累加,于是就产生了和GCC不相同的运算结果
通过汇编只是说明一下,这种用法在不同的编译环境下无法预知其结果,所以应该避免这种用法,也不要试图在未知环境中预测这种用法的行为
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
如按优先级和结合性的做题顺序应该是p=5+6+7=18,q=6+7+8=21的,可运行出的结果是p=15,q=22,刚查了些资料,据说是vc6.0本身的算法问题,p中的三个表达式统一先取i值给表达式,最后i的值再顺序加1,即p=5+5+5=15,i=5+1+1+1=8,q的值是先同时取前两个j+1的值,再加第三项,最后j的值再顺序加1,即q=(5+1+1)+(5+1+1)+(5+1+1+1)=22,j=5+1+1+1=8,纠结了吧?无语了吧?呵呵,就此执行吧,不要问为什么,哈哈
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
先说++在前 和++在后的情况吧 如第一个p=(i++)+(i++)+(i++)这里i原来等于5 三个++都在i的后面,所以 在这个计算中i一直都是5,所以p=5+5+5=15,而第二个 q=(++j)+(++j)+(++j)这个三个++都在j前面所以都是先自加1然后在计算 ,所以就是q=(5+1)+((5+1)+1)+((5+1+1)+1)=22,j=++j,j就会变成6所以后面的j都是在前面的++后的j的值用来计算的 这样 能看得懂吗 不懂再问我吧
希望我的回答对你有所帮助
希望我的回答对你有所帮助
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询