Chinaunix

标题: i = i++; [打印本页]

作者: bysea51    时间: 2004-10-22 09:47
标题: i = i++;
public static void main(String[] args){
                int i = 0;
                i = i ++;
                System.out.println("i = " + i);
        }

我想问的是为什么输出的结果是
i = 0

就算是先执行“i = i”,可是i 的自加不还是要执行的吗?
作者: pause    时间: 2004-10-22 10:04
标题: i = i++;
i++ 表达式的值是0.
你把i++的表达式的值赋给了i
那你说i的值是多少呢???
作者: demon-duke    时间: 2004-10-22 10:15
标题: i = i++;
这个问题很有意思
你可以去看看编译以后的字节码
看看它是怎么个执行顺序
作者: sakulagi    时间: 2004-10-22 10:22
标题: i = i++;
如果用i++和++i的话可以看到编译后的bytecode里iinc和iload的顺序不同。
作者: bysea51    时间: 2004-10-22 16:32
标题: i = i++;
十分感谢大家,我用javap看了,不管是i = i++;还是i = ++i;其后都有一个istore_1,是用来赋值的吧,对于i++来说堆栈中的0一直都没改过,所以一执行istore_1,就把i的自加给毁了。
作者: demon-duke    时间: 2004-10-22 17:30
标题: i = i++;
javap是什么东东?
作者: ilcj    时间: 2004-10-22 19:35
标题: i = i++;
javap是一个Java类分解工具。它能够将一个类分解为一个字节码的描述,在这些描述中告诉了你在没有进行实际的反编译类之前的一个实现是什么样的。和javac不同,javap使用class文件而不是源文件。
作者: 天下幽思    时间: 2004-10-24 18:12
标题: i = i++;
这个是不是Java本身的BUG。
istore_1是什么意思,出现了两次。
作者: 天下幽思    时间: 2004-10-24 18:31
标题: i = i++;
我明白了。
i=i++;
i++执行的结果在istrore_1中,(是不是这样,请指教)
由于有关“i ”的操作没有了。所以没有再次iload
就是说变量“i”的内存空间里面没有立即改变。
这么解释的话,JAVA似乎有BUG啊。
作者: 镖师甲    时间: 2004-10-24 20:26
标题: i = i++;
i++的情况
iconst_0
istore_1
iload_1
iinc 1,1
istore_1

++i的情况
iconst_0
istore_1
iinc 1,1
iload_1
istore_1
作者: 镖师甲    时间: 2004-10-24 20:29
标题: i = i++;
从上边来看只有iload_1和iinc 1,1是颠倒的.我怎么没体会到为什么i++的时候会输出0.如果istore_1代表存储i,那么不管上边的什么顺序,最后不都是i加一并且被存储了吗.紧接着下边用一个iload_1来去i的值.但是为什么不出现预期的结果呢?
作者: 镖师甲    时间: 2004-10-24 20:35
标题: i = i++;
除非一种情况,JVM会因为某种原因来调整指令的执行顺序
作者: 天下幽思    时间: 2004-10-25 12:57
标题: i = i++;
最后不都是i加一并且被存储了吗.

问题是存在那里?
作者: bysea51    时间: 2004-10-25 14:14
标题: i = i++;
在这里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。
作者: 白色乌鸦    时间: 2004-10-25 16:21
标题: i = i++;
楼上说得好清楚,
不知道从哪里可以看到这样的知识?
作者: 镖师甲    时间: 2004-10-25 20:37
标题: i = i++;
原帖由 "bysea51" 发表:
在这里jvm里面有两个存储区,一个是暂存区(是一个堆栈,以下称为堆栈),另一个是变量区。
语句istore_1是将堆栈中的值弹出存入相应的变量区(赋值);语句iload_1是将变量区中的值暂存如堆栈中。
因为i = i++;是..........

描述的挺有道理,但不明白,为什么要直接对变量区的进行++而不对临时的堆栈先加然后在存储到变量区呢?
作者: 镖师甲    时间: 2004-10-25 20:45
标题: i = i++;
bysea51说的应该是正确的,单执行情况i++的时候只有一个iinc 1,1.
应该是改变bysea51所说的变量区的东西.顺便问一问bysea51,iinc 1,1.
指令在JVM规范里应该有的吧,我没有看过,有空看看.哈哈.
作者: 镖师甲    时间: 2004-10-25 20:47
标题: i = i++;
果然是JVM的Instruction
作者: sakulagi    时间: 2004-10-25 21:21
标题: i = i++;
原帖由 "白色乌鸦" 发表:
楼上说得好清楚,
不知道从哪里可以看到这样的知识?
Java VM Specification
作者: sakulagi    时间: 2004-10-25 21:25
标题: i = i++;
原帖由 "镖师甲" 发表:

描述的挺有道理,但不明白,为什么要直接对变量区的进行++而不对临时的堆栈先加然后在存储到变量区呢?
这个要看表达式的值的定义了。因为按照JVM Spec,任何一个算术操作都是把最终的表达式的计算结果放到Operand Stack里。
所以在定义了“i++这个操作的表达式的值为i,而不是i+1”之后,i++的计算过程中,Operand Stack实际上并不用变化。所以无论是从Operand Stack里进行inc还是直接对变量区进行inc,结果都是一样的:Operand Stack没变,变量区加一。
作者: qianwj    时间: 2004-10-26 12:38
标题: i = i++;
i=++i
作者: blackcode    时间: 2004-11-01 14:38
标题: i = i++;
:em11:
#include <iostream>;
using std :: cout ;
using std :: endl ;
main()
{
  int i = 0;
  i = i ++;
  cout << "i = " << i << endl ;
  
}
但在C++里上面输出的确是1呀,跟教科书上说的一样呀。
作者: xkhwj    时间: 2004-11-02 15:20
标题: i = i++;
深刻呀。好好研究java
作者: tinywind    时间: 2004-11-02 15:30
标题: i = i++;
i=i++在c中属于未定义的情况,可以用两种方式处理:
1)i++;i=i
2)temp=i;i++;i=temp
但在java中是明确规定使用后一种方式
作者: hills    时间: 2004-11-02 16:22
标题: i = i++;
`   

    楼上几位说得都正确的。

    因为先赋值后为0了,因此后面的++将被忽略。

    这就像公式一样,记住就好了。

    学习一门计算机语言,很多规则是要死记而活用的!

     :em11:
作者: jamesbang2003    时间: 2005-03-02 14:55
标题: i = i++;
请问一下,javap是如何使用的,谢谢
作者: paladin00    时间: 2009-06-30 10:43
java的编译器在遇到i++和i- -的时候会重新为变量运算分配一块内存空间,以存放原始的值,而在完成了赋值运算之后,将这块内存释放掉.

(转)http://java.chinaitlab.com/base/21363.html
作者: aaaaa5aa    时间: 2009-07-01 12:22
这种问题不要讨论,没什么大意义
作者: aaaaa5aa    时间: 2009-07-01 12:27
这种问题不要讨论,没什么大意义
作者: freelogin    时间: 2009-07-02 14:53
那意思是i使用过后+1
int i=0;
i=++i;
System.out.println(i);
i=1
作者: chance_xym    时间: 2009-07-02 22:44
从来不用i=i++,只用i=i+1




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2