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
{
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
x=x;x++
x=x;x++
---------------------
这样的话结果就是1,1了
在这里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文件而不是源文件。)
x=0;
x=x++;x++ 等于多少? 0
此时 x =1;
但接下来又给x赋了新值x =(x++);也就是 x 又赋值为 0
原题不好理解:
x=x++;
我们来改为:
int z=x++;
显然:
z的值在前个语句执行后:
z=0,right?
那么z换成变量x有什么不同呢?
显然没有任何不同!
所以输出的结果是:
0
0
而事实上问题的关键不在这里,问题的关键其实在于,为什么第一个print语句输出的是0, 不知道是不是这样,但是 hello132(hell123) 的解释是令人信服的。
print(x);
x=x+1;
y=x
print(y);
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
int y = x = x++;大家分析分析下x、y的值分别是多少?
int y = x = x++;大家分析分析下x、y的值分别是多少?
还是0,0
CSDN小助手是一款脱离浏览器也可以访问Csdn论坛的软件
界面:http://blog.csdn.net/Qqwwee_Com/archive/2005/11/05/523395.aspx
下载:http://szlawbook.com/csdnv2
到底是什么地方不对.
JAVA是对值对像操作~~这个中复制了值对像进行操作~~结果以前的那个值对象失去引用~~结果就是1了~对Y的赋值是干挠没意义
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}
相信现在很清楚了!
都很有见解
虽然有不少专业的解说
不过仅仅对这个问题来说
鄙人认为最为经典
极易理解的就是 fropen()的变通方法至于C与JAVA机制不同
从而结果不同的情况
值得深入探讨敬佩
很容易理解
x=0;
x=x++;x++ 等于多少? 0
此时 x =1;
但接下来又给x赋了新值x =(x++);也就是 x 又赋值为 0
-----------------------------------------------高人.... 服了.....
楼上那位很厉害啊把x = x++ 的实现过程分解开来看首先这行代码的目的就是要给 x 执行 = 运算;这样就必须先求出 = 符号右边的值x++ 返回的值为 0 , 然后将 0 这个值存于堆栈中此时 x++ 运算已经结束了 , x 被赋值为 1最后将已经存于堆栈中的那个 0 对 x (此 x 还是有很小的一段时间等于 1 的) 执行 = 运算结果就是 x = 0 了以后的 y 的赋值就纯属无意义的行为了
最透彻了。java版真有趣。
先计算表达式的值,再赋值, (x++)是一个表达式,它的计算结果是0,计算完后x自增为1,随后又被赋值符"="赋值为0,x最后就是0。
在C里,可能是先赋值,再自增。
其实x=x++就是一次赋值,而x++就是将一个0赋给给x,而在这次赋值中,
无论x曾经变成了什么最终都会被赋值为0.多谢hello132,netpotRL两位仁兄
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++这个复制语句会创建一个副本
System.out.println(x);
System.out.println(x++);
System.out.println(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进行自加了再付值
x=x++先付值的话,此时x=0;再对原的x++,此时x不就等于1了吗,
讨论了这么多,觉得大家都是用自己的理解来解释,如果要真正的搞懂就只有去
好好的研究一下java虚拟机,正如c++里面的值为1,而java里面的值为0,这些都是他们底层的
实现机制来决定的.再讨论下去没有意义,如果想真正弄懂,就研究java虚拟机!
x=x++;//x1=x;x++;x=x1;
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。不知道我这样说你能不能理解。反正我是这么认为,不好意思。
假如你将你的程序写成
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++产生的结果。
int y = x++;
结果是 x=0;y=1;
int x=0;
int x=x++;
结果应该是x=1;
虽然是xx
需要大家首先认可下面这一点:符合运算符的优先顺序
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
不知道这个是否可以说明问题
虽然能够编译正确
但是我们认为它是错误的
做项目时 严禁使用此种写法
这属于裸机错误,是未定义行为
说不定java se6里面,这值就是1,1了
考虑: x=x++;
在虚拟机器里面,由于x++需要堆栈的配合,所以首先将x当前值压入堆栈(0入栈)。
然后x自动加一,现在x变为1。然后按照x++的原则,将自加之前的值赋值给等号前面的变量(现在X变为0)。
上面就是全部过程。有的人说y=x++是先执行y=x,然后在执行x=x+1.其实这种说法有错。
通过上面的分析我们知道x仍然是先执行自加然后将自己以前的一个副本赋值给了y。
这样考虑就非常清楚了。
至于C++如何执行,希望后面的兄弟能够象 hello132(hell123)和mengxiaoyong() 一样,拿出依据,找到权威的解释。
如果你在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的内部怎么做的了
如果你在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的内部怎么做的了这才是王道!!!!!!!!!!!!!!!!!!!!
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;
楼上那位很厉害啊把x = x++ 的实现过程分解开来看首先这行代码的目的就是要给 x 执行 = 运算;这样就必须先求出 = 符号右边的值x++ 返回的值为 0 , 然后将 0 这个值存于堆栈中此时 x++ 运算已经结束了 , x 被赋值为 1最后将已经存于堆栈中的那个 0 对 x (此 x 还是有很小的一段时间等于 1 的) 执行 = 运算结果就是 x = 0 了以后的 y 的赋值就纯属无意义的行为了/////////////////////////////////////////////////////eclipse 中的警告是因为其中 赋值 1 给 x 的那部分内容被无效化了而且 eclipse 中的警告和 jvm 几乎没有关系~~
但我想只要是一个java爱好者,都喜欢将每一个问题分析的明明白白不可,这样才不失追求"精通"之道.谢谢楼主出的题目.
刚装的 3.1.2 啊……
x=x++的结果可想而知是多少,只是有自增操作是在赋值前还是赋值后这样的变化啦,这就是java与c的不同,C是基于编译器的,前面有人谈到了
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(第二种情况)头都大了,这样理解好了。