Java JavaScript Web2.0

WWW World, Jack's World
posts - 9, comments - 28, trackbacks - 0, articles - 0
  BlogJava :: 首页 ::  :: 联系 :: 聚合  :: 管理

Java中的++操作

Posted on 2007-09-20 16:50 Jack L 阅读(1529) 评论(20)  编辑  收藏 所属分类: Java





    本文正文及所有讨论的整理稿发布于:http://webdn.trueself.cn/archives/7






    有这样一段代码
1     int a=1;
2     a=(4+(a++));
3     System.out.println(a);
    输出结果为5,而不是2或者6。自增操作在赋值操作之前,而不是之后。
    同理,语句a=a++;执行完成之后,a的值不会发生变化,而不是原来想像的自增1。
    下面解释运行机制:
   
    这段代码对应的Java字节码为:
1     iconst_1
2     istore_1
3     iconst_4
4     iload_1
5     iinc    #1      #1
6     iadd
7     istore_1
    解释:
    1~3行是声明变量a并赋值,并声明常量4
    4行,把a的值载入(存入一个临时地方);
    5行,通过一个指令iinc,实现a的自增1,并把新的结果存入原地点;
    6行,完成加法,关键在于,此处使用的a的值是第4行load进来时的值,而不是第5行完成自增操作后的值;
    7行,把存入结果a
    所以,自增操作发生在istore操作之前,所以最终a的值为5;

    为了更好的理解,下面给出另外一段代码:
 1     int i=1;
 2     i=(4+(++i));
 3     ios.println(i);
 4     //这段程序的执行结果显然为6
 5     //字节码为
 6     iconst_1
 7     istore_1
 8     iconst_4
 9     iinc    #1      #1
10    iload_1
11    iadd
12    istore_1




评论

# re: Java中的++操作  回复  更多评论   

2007-09-20 17:20 by 千里冰封
还研究的挺仔细的嘛,呵呵,竟然看字节码了

# re: Java中的++操作  回复  更多评论   

2007-09-20 17:39 by Jack L
千里兄过奖了
顺便补充一下,刚才我研究了JavaScript和C语言中的类似情况,发现JavaScript的结果与刚才讲的Java代码结果相同,但是C语言代码有明显不同的结果;
比如这段代码:
int i=1;
int t=(4+(i++));
执行完成之后,t的值为5,i的值为2;这个结果一点也不出乎意料
但是稍加改写
int i=1;
i=(4+(i++));
执行完成之后,i的值变成了6;如果这段交给Java虚拟机运行,如上面所示,结果是5;
所以,我的想法是,C语言中的++(位于操作数右边)在整条用分号结束的语句结束之后运行;相当于在该语句之后单独写一条i++语句。

# re: Java中的++操作  回复  更多评论   

2007-09-20 17:46 by Unmi
i=(4+(i++)); 这种写法会让人不知所然,既然i++了,又赋给i

# re: Java中的++操作  回复  更多评论   

2007-09-20 17:49 by Jack L
是的,现实中应该几乎没有这种写法,纯兴趣研究:)

# re: Java中的++操作  回复  更多评论   

2007-09-20 17:52 by Unmi
如果要看i=(4+(i++));在C++中执行就反汇编出来看看
7: int i=1;
00401798 mov dword ptr [ebp-4],1
8: i=(4+(i++));
0040179F mov eax,dword ptr [ebp-4]
004017A2 add eax,4
004017A5 mov dword ptr [ebp-4],eax
004017A8 mov ecx,dword ptr [ebp-4]
004017AB add ecx,1
004017AE mov dword ptr [ebp-4],ecx

# re: Java中的++操作  回复  更多评论   

2007-09-20 17:52 by Jack L
再进一步,考虑:
i=1;
i=(4+(i++)+(i++));
C语言的运行结果为8,Java和JavaScript的结果为7.
印证了我刚才对于C语言机制的想法,即++操作在整条语句之后执行;相加的值为(4+1+1)
在Java和JavaScript中,第二次load i的值时,++操作已经被执行过一次了,所以相加的值为(4+1+2)

# re: Java中的++操作  回复  更多评论   

2007-09-20 17:57 by Jack L
谢谢Unmi,看来在C语言中,++确实在最后执行,这与Java和JavaScript非常不一样。后者的++在表达式走出作用域的时候就执行,而不会等到整个语句结束。

# re: Java中的++操作  回复  更多评论   

2007-09-20 18:02 by teasp
二楼的实验也非常有意义。没想到c和java在这一点上还有区别,呵呵,学到了。不过有一点不太同意二楼说的,我觉得在c里面应该是 i=i++;和i=(i++);的区别,前者不会加1,后者会,而java中这两者是一样的。我说的仅仅是猜测,并没有实验过,说错了见谅

# re: Java中的++操作  回复  更多评论   

2007-09-20 18:03 by teasp
晕,没想到这么多人评论了。。。

# re: Java中的++操作  回复  更多评论   

2007-09-20 18:21 by 千里冰封
大家都挺能研究的

# re: Java中的++操作  回复  更多评论   

2007-09-20 18:48 by Jack L
teasp 说的二楼是我吗? 偶是楼主的说:)
我刚看了
执行下面两句
1: i=i++;
2: i=(i++);
在C中,执行完成之后,i的值均为2
在Java和JavaScript中,均为1

# re: Java中的++操作  回复  更多评论   

2007-09-20 19:09 by Unmi
总结一下,这样写
i=(4+(++i));
完全是给自己制造麻烦,代码不规范

极端一些,如果你碰到面试问你
int a=1;
int b=1;
int c= a++*b+++a++b;
你会去做这种题吗?
我会转身走人

# re: Java中的++操作  回复  更多评论   

2007-09-20 20:55 by Jack L
好玩就行,自己肯定不会这样编码的:)

# re: Java中的++操作  回复  更多评论   

2007-09-20 21:40 by teasp
@Jack L

是的。我猜错了,呵呵

# re: Java中的++操作  回复  更多评论   

2007-09-21 00:59 by dc
奇怪,难道连括号也保证不了运算的优先级?

# re: Java中的++操作  回复  更多评论   

2007-09-21 01:17 by piaoyi
a++和++a是不同的,在java中本來就有分,一個是先把值return出去再自加,一個是自加後才return,因為你的寫法是a++,所以先return的值是1,再和4相加就是5且又指給a,這樣後來的a自加就沒有用了

# re: Java中的++操作  回复  更多评论   

2007-09-21 09:31 by Jack L
是符合语义的。++操作的优先级本来就大于加号,所以一直不用写括号,写括号只是为了可读性@dc

# re: Java中的++操作  回复  更多评论   

2007-09-21 09:32 by Jack L
是的,Java和JavaScript是这样的,但是你看前面的评论,C语言中,a++在整个语句(用分号结束的语句)结束之后才执行。这是关键。@piaoyi

# re: Java中的++操作  回复  更多评论   

2007-09-21 10:17 by 千里冰封
呵呵,看似简单的操作,实际并不简单:)

# re: Java中的++操作  回复  更多评论   

2007-09-21 10:48 by 全凭一颗心
研究的挺多,激发了我的研究热情,XX(谢谢)楼上各位!

只有注册用户登录后才能发表评论。


网站导航: