x--的一点疑问 int x = 10; x -= x--; 此时x应当等于多少。本人在c++和java环境中分别运行过这段代码,在c++中运行结果是-1;但在java中运行结果是0;这难道是java处理中的bug? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 x = x - x ; 相当于x = x - x--;但是x--是先赋值再-1,所以计算的时候x=10所以 x = 10 - 10 = 0要是写成x -= --x;因为--x是先-1再赋值,所以计算的时候x=9所以 x = 10 - 9 = 1 然后又试了这么一段代码 int x = 10; x = x--; 这段代码在c++ 中输出是9,但java中输出的是10 我都说了,在java中,x--只对下一句的赋值有效,--x才对当前有效。 int x = 10; int y = x--; int z = x; System.out.println("y=" + y); // y=10 System.out.println("z=" + z); // z=9 x = 10; y = --x; z = x; System.out.println("y=" + y); // y=9 System.out.println("z=" + z); // z=9 学C/C++的同志们最好也学点汇编的知识,很多问题看下反汇编代码就一目了然了。x++、x--在C/C++和Java、C#中的处理方式是不一样的。以LZ例子来说,x-=x--;在VC中的反汇编代码是: x-=x--;004113C5 mov eax,dword ptr [x] 004113C8 sub eax,dword ptr [x] 004113CB mov dword ptr [x],eax ;前面三行实质上完成了x-=x的功能,这时x=0004113CE mov ecx,dword ptr [x] 004113D1 sub ecx,1 004113D4 mov dword ptr [x],ecx ;后面三行实质上是对x自减,完成后x=-1C/C++对x++、x--处理方式总结起来是:先以x原值参与表达式计算,然后再对x进行自增或自减。再看个更极端的例子吧: x-=(++x)+(++x); 计算结果是x=-12[code=Assembly] x-=(++x)+(++x);004113C5 mov eax,dword ptr [x] 004113C8 add eax,1 004113CB mov dword ptr [x],eax 004113CE mov ecx,dword ptr [x] 004113D1 add ecx,1 004113D4 mov dword ptr [x],ecx ;前面连续完成了2次对x的自增,使x=12004113D7 mov edx,dword ptr [x] 004113DA add edx,dword ptr [x] 004113DD mov eax,dword ptr [x] 004113E0 sub eax,edx 004113E2 mov dword ptr [x],eax ;后面实质上是对表达式x-=x+x的处理,完成后x=-12[code]可见C/C++中x++、++x中的"先序"与"后序"是相对于表达式的计算而言的。C/C++的处理方式重要的一点是不会使用中间变量,符合其高效的特点。 在Java、C#中x++、++x的"先序"与"后序"则是相对于自增、自减运算的返回值来说的。它们一般不会太注重效率,使用中间变量来储存每个自增、自减运算的返回值,使得运算更符合一般的思维逻辑。测试程序: public static void main(String[] args) { int x = 10; x -= x--; System.out.println(x); x = 10; x -= (++x) + (++x); System.out.println(x); }在下只抄录一下运算相关的字节码: 0: bipush 10 2: istore_1 //x=10; 3: iload_1 4: iload_1 5: iinc 1, -1 8: isub 9: istore_1 //x-=x--; 17: bipush 10 19: istore_1 //x=10; 20: iload_1 21: iinc 1, 1 24: iload_1 25: iinc 1, 1 28: iload_1 29: iadd 30: isub 31: istore_1 //x-=(++x)+(++x);说实话,上面的字节码在下也看得一头雾水。贴出来只是想请看得懂的同志帮忙解释下。由于C#在许多问题上的处理方式与Java一致,所以在下从C#的汇编代码入手分析: int x = 10;00000035 mov dword ptr [ebp-40h],0Ah x -= x--;0000003c mov eax,dword ptr [ebp-40h] 0000003f mov dword ptr [ebp-44h],eax 00000042 mov eax,dword ptr [ebp-40h] 00000045 mov dword ptr [ebp-48h],eax 00000048 dec dword ptr [ebp-40h] 0000004b mov eax,dword ptr [ebp-44h] 0000004e sub eax,dword ptr [ebp-48h] 00000051 mov dword ptr [ebp-40h],eax x = 10;0000005d mov dword ptr [ebp-40h],0Ah x -= (++x) + (++x);00000064 mov eax,dword ptr [ebp-40h] 00000067 mov dword ptr [ebp-4Ch],eax 0000006a inc dword ptr [ebp-40h] 0000006d mov eax,dword ptr [ebp-40h] 00000070 mov dword ptr [ebp-50h],eax 00000073 inc dword ptr [ebp-40h] 00000076 mov eax,dword ptr [ebp-4Ch] 00000079 mov edx,dword ptr [ebp-50h] 0000007c add edx,dword ptr [ebp-40h] 0000007f sub eax,edx 00000081 mov dword ptr [ebp-40h],eax 对x-=x--,C#用了2个中间变量[ebp-44h]和[ebp-48h],一个用来记录x的返回值(因为x也要参与表达式的运算),记为temp1;另一个用来记录x--的返回值,记为temp2。x-=x--即x=x-(x--)的实质是:temp1=x; //x的原始值temp2=x; //x--的返回值x--;x=temp1-temp2;对x-=(++x)+(++x),也用了2个中间变量[ebp-4Ch]和[ebp-50h],一个用来记录x的返回值,记为temp1;另一个用来记录第一个++x的返回值,记为temp2;至于第二个++x的返回值,可以用x自身[ebp-40h]记录,故可省略第三个中间变量。x-=(++x)+(++x)即x=x-((++x)+(++x))的实值是:temp1=x; //x的原始值++x;temp2=x; //第一次++x的返回值++x; //这时x([ebp-40h])记录的是第二次++x的返回值x=temp1-(temp2+x); //temp1放eax,temp2+x放edx然后sub...... 应该是两种语言的运算顺序不一样,java是先计算x--的值,为10,然后x = x - 10,最后答案是0 了解下运行机制即可,千万别把这样的代码写到你项目中,你老大review你代码看到这个批死你不可 string indexOf startWith contains 的效率,谁高谁低? 在寻找通过SNMP实时监测服务器性能的Java项目 key可以相同,value不同,但value的值要求不重复,用什么保存好,或者有什么好的保存方式? Class Cast 用jsp如何将文件压缩/释放,小弟急啊...... 经过这几天的观察,我觉得一个midlet里应该有如下这么几个线程,它和application是不一样的 数组的问题!!?? Image 问题 请问那有jfc包下载 来呀...... 求高手指教 求高手编译!!!!!!!!!!!!
x = x - x--;
但是x--是先赋值再-1,所以计算的时候x=10
所以 x = 10 - 10 = 0要是写成x -= --x;
因为--x是先-1再赋值,所以计算的时候x=9
所以 x = 10 - 9 = 1
int x = 10;
x = x--;
这段代码在c++ 中输出是9,但java中输出的是10
int x = 10;
int y = x--;
int z = x;
System.out.println("y=" + y); // y=10
System.out.println("z=" + z); // z=9
x = 10;
y = --x;
z = x;
System.out.println("y=" + y); // y=9
System.out.println("z=" + z); // z=9
004113C5 mov eax,dword ptr [x]
004113C8 sub eax,dword ptr [x]
004113CB mov dword ptr [x],eax ;前面三行实质上完成了x-=x的功能,这时x=0
004113CE mov ecx,dword ptr [x]
004113D1 sub ecx,1
004113D4 mov dword ptr [x],ecx ;后面三行实质上是对x自减,完成后x=-1C/C++对x++、x--处理方式总结起来是:先以x原值参与表达式计算,然后再对x进行自增或自减。再看个更极端的例子吧: x-=(++x)+(++x); 计算结果是x=-12
[code=Assembly]
x-=(++x)+(++x);
004113C5 mov eax,dword ptr [x]
004113C8 add eax,1
004113CB mov dword ptr [x],eax
004113CE mov ecx,dword ptr [x]
004113D1 add ecx,1
004113D4 mov dword ptr [x],ecx ;前面连续完成了2次对x的自增,使x=12
004113D7 mov edx,dword ptr [x]
004113DA add edx,dword ptr [x]
004113DD mov eax,dword ptr [x]
004113E0 sub eax,edx
004113E2 mov dword ptr [x],eax ;后面实质上是对表达式x-=x+x的处理,完成后x=-12
[code]
可见C/C++中x++、++x中的"先序"与"后序"是相对于表达式的计算而言的。C/C++的处理方式重要的一点是不会使用中间变量,符合其高效的特点。
int x = 10;
x -= x--;
System.out.println(x);
x = 10;
x -= (++x) + (++x);
System.out.println(x);
}在下只抄录一下运算相关的字节码: 0: bipush 10
2: istore_1 //x=10;
3: iload_1
4: iload_1
5: iinc 1, -1
8: isub
9: istore_1 //x-=x--; 17: bipush 10
19: istore_1 //x=10;
20: iload_1
21: iinc 1, 1
24: iload_1
25: iinc 1, 1
28: iload_1
29: iadd
30: isub
31: istore_1 //x-=(++x)+(++x);说实话,上面的字节码在下也看得一头雾水。贴出来只是想请看得懂的同志帮忙解释下。由于C#在许多问题上的处理方式与Java一致,所以在下从C#的汇编代码入手分析: int x = 10;
00000035 mov dword ptr [ebp-40h],0Ah
x -= x--;
0000003c mov eax,dword ptr [ebp-40h]
0000003f mov dword ptr [ebp-44h],eax
00000042 mov eax,dword ptr [ebp-40h]
00000045 mov dword ptr [ebp-48h],eax
00000048 dec dword ptr [ebp-40h]
0000004b mov eax,dword ptr [ebp-44h]
0000004e sub eax,dword ptr [ebp-48h]
00000051 mov dword ptr [ebp-40h],eax
x = 10;
0000005d mov dword ptr [ebp-40h],0Ah
x -= (++x) + (++x);
00000064 mov eax,dword ptr [ebp-40h]
00000067 mov dword ptr [ebp-4Ch],eax
0000006a inc dword ptr [ebp-40h]
0000006d mov eax,dword ptr [ebp-40h]
00000070 mov dword ptr [ebp-50h],eax
00000073 inc dword ptr [ebp-40h]
00000076 mov eax,dword ptr [ebp-4Ch]
00000079 mov edx,dword ptr [ebp-50h]
0000007c add edx,dword ptr [ebp-40h]
0000007f sub eax,edx
00000081 mov dword ptr [ebp-40h],eax 对x-=x--,C#用了2个中间变量[ebp-44h]和[ebp-48h],一个用来记录x的返回值(因为x也要参与表达式的运算),记为temp1;另一个用来记录x--的返回值,记为temp2。
x-=x--即x=x-(x--)的实质是:
temp1=x; //x的原始值
temp2=x; //x--的返回值
x--;
x=temp1-temp2;
对x-=(++x)+(++x),也用了2个中间变量[ebp-4Ch]和[ebp-50h],一个用来记录x的返回值,记为temp1;另一个用来记录第一个++x的返回值,记为temp2;至于第二个++x的返回值,可以用x自身[ebp-40h]记录,故可省略第三个中间变量。
x-=(++x)+(++x)即x=x-((++x)+(++x))的实值是:
temp1=x; //x的原始值
++x;
temp2=x; //第一次++x的返回值
++x; //这时x([ebp-40h])记录的是第二次++x的返回值
x=temp1-(temp2+x); //temp1放eax,temp2+x放edx然后sub......
java是先计算x--的值,为10,然后x = x - 10,最后答案是0