int x = 10;
  x -= x--;
   此时x应当等于多少。本人在c++和java环境中分别运行过这段代码,
在c++中运行结果是-1;
但在java中运行结果是0;
这难道是java处理中的bug?

解决方案 »

  1.   

    x = x - x ; 
      

  2.   

    相当于
    x = x - x--;
    但是x--是先赋值再-1,所以计算的时候x=10
    所以 x = 10 - 10 = 0要是写成x -= --x;
    因为--x是先-1再赋值,所以计算的时候x=9
    所以 x = 10 - 9 = 1
      

  3.   

    然后又试了这么一段代码
       int x = 10;
       x = x--;
       这段代码在c++ 中输出是9,但java中输出的是10
      

  4.   

    我都说了,在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
      

  5.   

    学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=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++的处理方式重要的一点是不会使用中间变量,符合其高效的特点。
      

  6.   

    在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......
      

  7.   

    应该是两种语言的运算顺序不一样,
    java是先计算x--的值,为10,然后x = x - 10,最后答案是0
      

  8.   

    了解下运行机制即可,千万别把这样的代码写到你项目中,你老大review你代码看到这个批死你不可