一个简单的C程序解决思路
一个简单的C程序
include <stdio.h>
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);
} q的结果为什么是22,不是21
------解决方案--------------------
与编译器有关。。。
------解决方案--------------------
Undefined
------解决方案--------------------
看反汇编!
------解决方案--------------------
对于这些运算符产生的Side Effect,编译器可以任意选择各个Side Effect的作用顺序。
------解决方案--------------------
这种问题只有在书本上可以看到,在实际的工程应用中是不会出现的,因为不同的编译器产生的结果会有所不同。
------解决方案--------------------
------解决方案--------------------
q是22么,应该是24吧,先算++j,实际上是3个8相加了吧
------解决方案--------------------
这个六个编译器把
------解决方案--------------------
------解决方案--------------------
LZ,真没必要纠结
这个不同的编译器,答案不同的
如果你要搞清楚你的编译器的规则
建议看反汇编,那里一步一步的计算过程
------解决方案--------------------
int j=4;
int a = i++ + i++;
int b = ++j + ++j;
printf("%d, %d\n", a, b);
问题又来了,i++ + i++是先自增一次,相加,再自增,然后赋值呢,还是先相加赋值然后自增两次呢。另外,++j又将如何表现呢?
结果是:6,12
这下明白了,原来 i++的理解应该是执行完整个表达式的其他操作后,然后才自增,所以例子中的a=3+3=6;而后i再自增2次,i=5;相反,++j是先自增然后再参加其它运算,所以b=6+6=12.
到此,是否就彻底明了了呢?然后回到引子中的问题
------解决方案--------------------
它应该是这样的,P=((++I)+(++i))+(++I)
------解决方案--------------------
同意二楼,不同编译器运行效果可能不一样。
------解决方案--------------------
让楼主弄得很艹计!我的输出的结果是15.24.8.8(vs2010英文旗舰版)!!!
------解决方案--------------------
这个就是教学用的c语言
------解决方案--------------------
月经贴
------解决方案--------------------
vs2008的编译结果
也就是一个语句中的++计算,要到语句结束的时候,才会反映到相应的寄存器。
; 5 : int p=(i++)+(i++)+(i++);
mov ecx, DWORD PTR [edx]
lea eax, DWORD PTR [ecx+ecx*2]
add ecx, 3
mov DWORD PTR [edx], ecx
------解决方案--------------------
不好意思,前面发错了。vs是24, 如果是21也能理解
22 确实不知道内部是怎么实现的。
; 5 : int p=(++j)+(++j)+(++j);
add DWORD PTR [eax], 3
mov eax, DWORD PTR [eax]
lea eax, DWORD PTR [eax+eax*2]
------解决方案--------------------
不同编译器的原因
------解决方案--------------------
------解决方案--------------------
我的编译器报警告,然后没输出
include <stdio.h>
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);
} q的结果为什么是22,不是21
------解决方案--------------------
与编译器有关。。。
------解决方案--------------------
Undefined
------解决方案--------------------
看反汇编!
------解决方案--------------------
对于这些运算符产生的Side Effect,编译器可以任意选择各个Side Effect的作用顺序。
------解决方案--------------------
这种问题只有在书本上可以看到,在实际的工程应用中是不会出现的,因为不同的编译器产生的结果会有所不同。
------解决方案--------------------
------解决方案--------------------
q是22么,应该是24吧,先算++j,实际上是3个8相加了吧
------解决方案--------------------
这个六个编译器把
------解决方案--------------------
------解决方案--------------------
LZ,真没必要纠结
这个不同的编译器,答案不同的
如果你要搞清楚你的编译器的规则
建议看反汇编,那里一步一步的计算过程
------解决方案--------------------
int j=4;
int a = i++ + i++;
int b = ++j + ++j;
printf("%d, %d\n", a, b);
问题又来了,i++ + i++是先自增一次,相加,再自增,然后赋值呢,还是先相加赋值然后自增两次呢。另外,++j又将如何表现呢?
结果是:6,12
这下明白了,原来 i++的理解应该是执行完整个表达式的其他操作后,然后才自增,所以例子中的a=3+3=6;而后i再自增2次,i=5;相反,++j是先自增然后再参加其它运算,所以b=6+6=12.
到此,是否就彻底明了了呢?然后回到引子中的问题
------解决方案--------------------
它应该是这样的,P=((++I)+(++i))+(++I)
------解决方案--------------------
同意二楼,不同编译器运行效果可能不一样。
------解决方案--------------------
让楼主弄得很艹计!我的输出的结果是15.24.8.8(vs2010英文旗舰版)!!!
------解决方案--------------------
这个就是教学用的c语言
------解决方案--------------------
月经贴
------解决方案--------------------
vs2008的编译结果
也就是一个语句中的++计算,要到语句结束的时候,才会反映到相应的寄存器。
; 5 : int p=(i++)+(i++)+(i++);
mov ecx, DWORD PTR [edx]
lea eax, DWORD PTR [ecx+ecx*2]
add ecx, 3
mov DWORD PTR [edx], ecx
------解决方案--------------------
不好意思,前面发错了。vs是24, 如果是21也能理解
22 确实不知道内部是怎么实现的。
; 5 : int p=(++j)+(++j)+(++j);
add DWORD PTR [eax], 3
mov eax, DWORD PTR [eax]
lea eax, DWORD PTR [eax+eax*2]
------解决方案--------------------
不同编译器的原因
------解决方案--------------------
------解决方案--------------------
我的编译器报警告,然后没输出