class Check4
{
public static void main(String args[])
{
       int x=0;
    x=x++;
    System.out.println(x);
    int y=x;
    System.out.println(y);
}
}
返回的是 0  0
为什么不是 0 1

解决方案 »

  1.   

    是因为x先赋值再执行x++的操作,所以原来的x还是0
      

  2.   

    叫我怎么说呢,这是一个很基础的东东,x++和++x的区别,前者为先引用X的值,再做+运算,后者是先做+运算,再取X的值
      

  3.   

    x=x++可以看成两个语句;
    x=x;x++
      

  4.   

    这个地方拆成两个语句反而不妥;x=x++ 是把x的值0给了前面的新x;老x+1;但是现在的新x依然是0
      

  5.   

    x=x++可以看成两个语句;
    x=x;x++
    ---------------------
    这样的话结果就是1,1了
      

  6.   

    我觉得应该是x执行了++,但是把原来的值0赋给了x,所以x还是0
      

  7.   

    我找到了一个比较合理和清楚的解释是这样的:
    在这里jvm里面有两个存储区,一个是暂存区(是一个堆栈,以下称为堆栈),另一个是变量区。 语句istore_1是将堆栈中的值弹出存入相应的变量区(赋值);语句iload_1是将变量区中的值暂存如堆栈中。 因为i = i++;是先将i的值(0)存入堆栈,然后对变量区中的i自加1,这时i的值的确是1,但是随后的istore_1又将堆栈的值(0)弹出赋给变量区的i,所以最后i = 0。 又因为i = ++i;是先对变量区中的i自加1,然后再将变量区中i的值(1)存入堆栈,虽然最后执行了istore_1,但也只是将堆栈中的值(1) 弹出赋给变量区的i,所以i = ++i;的结果是i = 1。利用的是javap工具(avap是一个Java类分解工具。它能够将一个类分解为一个字节码的描述,在这些描述中告诉了你在没有进行实际的反编译类之前的一个实现是什么样的。和javac不同,javap使用class文件而不是源文件。)
      

  8.   

    很容易理解
    x=0;
    x=x++;x++ 等于多少? 0 
    此时 x =1;
    但接下来又给x赋了新值x =(x++);也就是 x 又赋值为 0 
      

  9.   

    楼上那位很厉害啊把x = x++ 的实现过程分解开来看首先这行代码的目的就是要给 x 执行 = 运算;这样就必须先求出 = 符号右边的值x++ 返回的值为 0 , 然后将 0 这个值存于堆栈中此时 x++ 运算已经结束了 , x 被赋值为 1最后将已经存于堆栈中的那个 0 对 x (此 x 还是有很小的一段时间等于 1 的) 执行 = 运算结果就是 x = 0 了以后的 y 的赋值就纯属无意义的行为了
      

  10.   

    还没结分吧?
    原题不好理解:
    x=x++;
    我们来改为:
    int z=x++;
    显然:
    z的值在前个语句执行后:
    z=0,right?
    那么z换成变量x有什么不同呢?
    显然没有任何不同!
    所以输出的结果是:
    0
    0
      

  11.   

    楼上的假设并不好,你说的情况和lz说的情况不一样,int z = x++;谁都知道这里z被赋值零
    而事实上问题的关键不在这里,问题的关键其实在于,为什么第一个print语句输出的是0, 不知道是不是这样,但是 hello132(hell123) 的解释是令人信服的。
      

  12.   

    X++ 是等到下一次运算的时候才体现出加一来,第一次 y=x++,x的值是不变的,当执行y=x 的时候加一就表现出来了,这个时候y的值就是1了,使及程序运行顺序是 x=0;
    print(x);
    x=x+1;
    y=x
    print(y);
      

  13.   

    zez(思恩 闭关练功ing...) 很厉害啊^_^
      

  14.   

    int x=0;
        x=x++;
        System.out.println(x);
        int y=x;
        System.out.println(y);
    是这样的执行顺序,
    1、x=0,
    2、x=x++;//主要是这步,x++的优先级大于=,所以,先做x++,把x值先取出来准备参与运算,x++后x的值是1,而把x++之前的值给了x,所以x的值又是0.
    3、y=x;
    x=0->x=1->x=0->y=0
      

  15.   

    各位老大,如果将题目改为:
    int y = x = x++;大家分析分析下x、y的值分别是多少?
      

  16.   

    可以这样理解:x=x++分解成两条,z=x++;x=z;先执行x++,x变成1了,但是z被赋成了0,然后再把z赋给x,x又从1变成了0,所以x最后的结果是0
      

  17.   

    各位老大,如果将题目改为:
    int y = x = x++;大家分析分析下x、y的值分别是多少?
    还是0,0
      

  18.   

    路过====CSDN 小助手 V2.5 2005年11月05日发布====
    CSDN小助手是一款脱离浏览器也可以访问Csdn论坛的软件
    界面:http://blog.csdn.net/Qqwwee_Com/archive/2005/11/05/523395.aspx
    下载:http://szlawbook.com/csdnv2
      

  19.   

    大家可以考虑一下:JAVA的传值和传引用的!!!!
      

  20.   

    eclipse 果然强大 ,x=x++; 这行会有警告说对x付值无效
      

  21.   

    个人觉得研究这个问题还是值得。请不要看问题的表面,不要简单的去讨论i=i++的问题,应该看到他的本质,了解java运行的机理,在以后的编程过程中就能因此而通其它,这也是我们菜鸟和高手的区别把,
      

  22.   

    哈哈....同意楼上的看法...在C语言里运动起来就是1,1而在java里面就是0,0如果是高手就会想为什么..
    到底是什么地方不对.
      

  23.   

    C是1  1可能是因为C是以指针操作~~最后加回到那个地址的值了~~
    JAVA是对值对像操作~~这个中复制了值对像进行操作~~结果以前的那个值对象失去引用~~结果就是1了~对Y的赋值是干挠没意义
      

  24.   

    对这个类进行javap操作得到main方法的字节码如下:
    public static void main(java.lang.String[]);
      Code:
       Stack=2, Locals=3, Args_size=1
       0:   iconst_0   //将常量0压入操作数stack中
       1:   istore_1   //将常量0弹出操作数stack并将它符值给本地变量x,此时x=0
       2:   iload_1    //将本地变量x的值压入操作数stack中,此时x=0,stack中的值为0
       3:   iinc    1, 1    //将本地变量x直接执行自增操作,此时本地变量x的值为1,而操作数stack中的值仍为0
       6:   istore_1    //将操作数stack中的值0弹出符值给本地变量x,此时本地变量x的值变为了0
       7:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       10:  iload_1     //取得本地变量x的值压入操作数stack,此时的值为0
       11:  invokevirtual   #3; //Method java/io/PrintStream.println:(I)V  //打印出操作数stack中值0,并将0弹出stack
       14:  iload_1      //取得本地变量x的值压入stack,此时的值为0
       15:  istore_2     //将操作数stack中的值0弹出符值给本地变量y
       16:  getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       19:  iload_2      //取得本地变量y的值压入stack,此时的值为0
       20:  invokevirtual   #3; //Method java/io/PrintStream.println:(I)V   //打印出操作数stack中值0,并将0弹出stack   23:  return
      LineNumberTable:
       line 5: 0
       line 6: 2
       line 7: 7
       line 8: 14
       line 9: 16
       line 10: 23}
    相信现在很清楚了!
      

  25.   

    相信hello123(hello123),mengxiaoyong,认为有理由
      

  26.   

    遇到不少高手
    都很有见解
    虽然有不少专业的解说
    不过仅仅对这个问题来说
    鄙人认为最为经典
    极易理解的就是 fropen()的变通方法至于C与JAVA机制不同
    从而结果不同的情况
    值得深入探讨敬佩
      

  27.   

    回复人: zez(思恩 闭关练功ing...) ( ) 信誉:176  2005-12-16 10:35:19  得分: 0  
     
     
       
    很容易理解
    x=0;
    x=x++;x++ 等于多少? 0 
    此时 x =1;
    但接下来又给x赋了新值x =(x++);也就是 x 又赋值为 0 
    -----------------------------------------------高人.... 服了.....
      
     
      

  28.   

    回复人: netpotRL(JAVA精神BEAN) ( ) 信誉:100  2005-12-16 11:49:26  得分: 0  
     
     
       
    楼上那位很厉害啊把x = x++ 的实现过程分解开来看首先这行代码的目的就是要给 x 执行 = 运算;这样就必须先求出 = 符号右边的值x++ 返回的值为 0 , 然后将 0 这个值存于堆栈中此时 x++ 运算已经结束了 , x 被赋值为 1最后将已经存于堆栈中的那个 0 对 x (此 x 还是有很小的一段时间等于 1 的) 执行 = 运算结果就是 x = 0 了以后的 y 的赋值就纯属无意义的行为了  
     
    最透彻了。java版真有趣。
      

  29.   

    x=x++
    先计算表达式的值,再赋值, (x++)是一个表达式,它的计算结果是0,计算完后x自增为1,随后又被赋值符"="赋值为0,x最后就是0。
    在C里,可能是先赋值,再自增。
      

  30.   

    各位仁兄都有见解…… hello132,netpotRL都说出了根本的原因,
    其实x=x++就是一次赋值,而x++就是将一个0赋给给x,而在这次赋值中,
    无论x曾经变成了什么最终都会被赋值为0.多谢hello132,netpotRL两位仁兄
      

  31.   

    把你刚才的程序稍微改一下
         class Check4
    {
    public static void main(String args[])
    {
           int x=0;
        x++;
        System.out.println(x);
        int y=x;
        System.out.println(y);
    }
    }
    结果是1  1
    你原来的程序x=x++是先把x++放入新的x中,值还是为0,而后面再次调用的x是新的x,所以值一直是0
    我改的程序执行到x++后,回将结果放入原来的x中,值为1,后面再次调用的x只都为1 
    也就是x=x++这个复制语句会创建一个副本
      

  32.   

    在C语言里面,++这个运算符,没有明确规定先取值(0)再运算,还是先运算再取值(1)。因此,在C语言里面,x=x++的结果要看编译器是怎么实现++这个运算符的。Java沿用了C的这个操作符,同时为了避免混淆,明确规定了这个运算符是先取值(0),再运算。所以,在Java里面,x=x++始终是0。
      

  33.   

    int x=0;
    System.out.println(x);
    System.out.println(x++);
    System.out.println(x);你就知道怎么回事了
      

  34.   

    问题的关键已经不是前增和后增,而是怎么看待x,x=x++;这里x赋值是怎么赋的?hello132(hell123)解释的很清楚。
      

  35.   

    hello132(hell123) 解释的好!!
      

  36.   

    那你们又如何解释for(int i=0;i<10;i++){}呢,这个问题好像和上面很多人所说的结果产生冲突了!
      

  37.   

    x=x++的执行顺序是
    x=x;
    system.out.println(x);
    x=x+1;y=x;
    syste.out.println(y);x++和++x是不同的.x=x++是先付值.再对原的x+1;
    x=++x;
    是先对x进行自加了再付值
      

  38.   

    楼上说的:x++和++x是不同的.x=x++是先付值.再对原的x+1;
    x=x++先付值的话,此时x=0;再对原的x++,此时x不就等于1了吗,
    讨论了这么多,觉得大家都是用自己的理解来解释,如果要真正的搞懂就只有去
    好好的研究一下java虚拟机,正如c++里面的值为1,而java里面的值为0,这些都是他们底层的
    实现机制来决定的.再讨论下去没有意义,如果想真正弄懂,就研究java虚拟机!
      

  39.   

    错了,应该是
    x=x++;//x1=x;x++;x=x1; 
      

  40.   

    因为在你的程序
    1  public class Check4
    2  {
    3  public static void main(String args[])
    4  {
    5       int x=0;
    6    x=x++;
    7    System.out.print(x);
    8    int y=x;
    9    System.out.print(y);
    10 }
    11 }
    中,在6行,x=x++;等号左边的X是赋值变量,而等好右边的X++的运算结果赋值给等号左边的X。所以在程序运行到第7行,输出的是第6行等号左边的X,而不是等号右边的X。不知道我这样说你能不能理解。反正我是这么认为,不好意思。
      

  41.   

    补充;
    假如你将你的程序写成
    1  public class Check4
    2  {
    3  public static void main(String args[])
    4  {
    5       int x=0;
    6    x++;
    7    System.out.print(x);
    8    int y=x;
    9    System.out.print(y);
    10 }
    11 }
    这样,他肯定输出的是11,因为从第6行起,程序就开始用第6行X++产生的结果。
      

  42.   

    int x = 0;
    int y = x++;
    结果是 x=0;y=1;
    int x=0;
    int x=x++;
    结果应该是x=1;
    虽然是xx
      

  43.   

    说明一个问题:
    需要大家首先认可下面这一点:符合运算符的优先顺序
    x = x++; 等同于 x = (x++);
    那么再执行如下代码:public class Check4
    {
     public static void main(String args[])
     {
      Check4 cc = new Check4();
      cc.test();
     }
     public void test()
     {
      int x=0;
      System.out.println(x++);
      x=0;
      System.out.println(x);
      int y=x;
      System.out.println(y);
     }
    }
    执行结果如下:
    0
    0
    0
    不知道这个是否可以说明问题
      

  44.   

    x=x++;这表达试
    虽然能够编译正确
      但是我们认为它是错误的
        做项目时 严禁使用此种写法 
        这属于裸机错误,是未定义行为
       说不定java se6里面,这值就是1,1了
      

  45.   

    hello132(hell123) 和mengxiaoyong() 的解释非常合理。
    考虑: x=x++;
    在虚拟机器里面,由于x++需要堆栈的配合,所以首先将x当前值压入堆栈(0入栈)。
    然后x自动加一,现在x变为1。然后按照x++的原则,将自加之前的值赋值给等号前面的变量(现在X变为0)。
    上面就是全部过程。有的人说y=x++是先执行y=x,然后在执行x=x+1.其实这种说法有错。
    通过上面的分析我们知道x仍然是先执行自加然后将自己以前的一个副本赋值给了y。
    这样考虑就非常清楚了。
    至于C++如何执行,希望后面的兄弟能够象 hello132(hell123)和mengxiaoyong() 一样,拿出依据,找到权威的解释。
      

  46.   

    最重要是x=x++;这一句,
    如果你在eclipse中输入,他会提示The assignment to variable a has no effect
    也就是说,这样的结构虽然语法上没错,但是jvm对这种结果的处理却和
    int a=0;
    x=x+a++;的结果是不一样的,对于x=x++;jvm无法给于x赋值
    也就是说第一步,先执行了,x++因为,x++的语法是先执行x在等于后在执行++所以现在x=0;
    第二步,x=x 在这里就有问题了,会有The assignment to variable a has no effect错误
    第三步才执行x=x+1;(x++)但这一步却无法执行,因为第二步的关系,更多的就要看jvm的内部怎么做的了
      

  47.   

    最重要是x=x++;这一句,
    如果你在eclipse中输入,他会提示The assignment to variable a has no effect
    也就是说,这样的结构虽然语法上没错,但是jvm对这种结果的处理却和
    int a=0;
    x=x+a++;的结果是不一样的,对于x=x++;jvm无法给于x赋值
    也就是说第一步,先执行了,x++因为,x++的语法是先执行x在等于后在执行++所以现在x=0;
    第二步,x=x 在这里就有问题了,会有The assignment to variable a has no effect错误
    第三步才执行x=x+1;(x++)但这一步却无法执行,因为第二步的关系,更多的就要看jvm的内部怎么做的了这才是王道!!!!!!!!!!!!!!!!!!!!
      

  48.   

    这个地方拆成两个语句反而不妥;x=x++ 是把x的值0给了前面的新x;老x+1;但是现在的新x依然是0
      

  49.   

    不好意思,经过刚才我在想了一下之后,在上面的基础上,我又得出以下结论.
    x=x++;
    在这先身明x=x这种语法是有问题的;
    接下来是深入分析
    为了理解方便,我在抽象化了一层左边x别名为x1右边x别名x2;x1=x2++;
    接着是
    第一步:x=x++;因为x开始等于零所以,在这就变成了x=0++;(但在这里"等号"还没有执行)
    第二步:右边x++自增也就是x=1;在这里x=1
    而接下来第三步执行x=0++;也就是说到现在才开始执行等号所以x本来是1的,又变成了0;
    到最后x=0;
      

  50.   

    不好意思啊,引用楼上自己的话~~回复人: netpotRL(←≮华丽的括号≯→)┅┅(JAVA精神BEAN) ( ) 信誉:100  2005-12-16 11:49:26  得分: 0  
     
       
    楼上那位很厉害啊把x = x++ 的实现过程分解开来看首先这行代码的目的就是要给 x 执行 = 运算;这样就必须先求出 = 符号右边的值x++ 返回的值为 0 , 然后将 0 这个值存于堆栈中此时 x++ 运算已经结束了 , x 被赋值为 1最后将已经存于堆栈中的那个 0 对 x (此 x 还是有很小的一段时间等于 1 的) 执行 = 运算结果就是 x = 0 了以后的 y 的赋值就纯属无意义的行为了/////////////////////////////////////////////////////eclipse 中的警告是因为其中 赋值 1 给 x 的那部分内容被无效化了而且 eclipse 中的警告和 jvm 几乎没有关系~~
      

  51.   

    很好的题目,让我们更深入的学习java的运行机制,在实际中是很少会写x=x++;这样的语句,
    但我想只要是一个java爱好者,都喜欢将每一个问题分析的明明白白不可,这样才不失追求"精通"之道.谢谢楼主出的题目.
      

  52.   

    为什么我的 Eclipse 对 x=x++; 没有给出任何提示信息?
    刚装的 3.1.2 啊……
      

  53.   

    用寄存器来理解,x++是一个表达式,放到一个寄存器里,x是一个变量,放在另一个寄存器里
    x=x++的结果可想而知是多少,只是有自增操作是在赋值前还是赋值后这样的变化啦,这就是java与c的不同,C是基于编译器的,前面有人谈到了
      

  54.   

    c# 的运行结果和JAVA的一样,看来 微软也继承了JAVA的这个“优越性”。    :~)
      

  55.   

    第一种情况
    int x=0;
    int y=x++;
    x++是先赋值后运算的吧
    y=0
    x=1--------------------------------
    第二种情况
    如果是
    int x=0;
    int y=++x;
    ++x是先运算后赋值的吧
    y=1
    x=1
    ----------------------------------
    如果是
    int x=0
    x=x++
    就相当于y=x++(第一种情况)
    --------------------------------------
    如果是
    int x=0
    x=++x
    就相当于y=++x(第二种情况)头都大了,这样理解好了。