A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

  1. public class Test {
  2.         public static void main(String[] args)
  3.         {
  4.                 int j=0;
  5.                 for(int i = 0; i<100; i++)
  6.                 {
  7.                         j =j++;//我凌乱了~~  这个执行顺序是怎样啊?
  8.                 }
  9.                 System.out.println(j);
  10.         }

  11. }
复制代码
结果是  0 ~~~~~~

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1 每次j都是0 还是前++ 后++的问题.

查看全部评分

22 个回复

正序浏览
本帖最后由 何旭栋 于 2012-5-22 19:51 编辑
  1. class Demo
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 int k = 3;
  6.                                 k += k++;
  7.                                 System.out.println(k);
  8.                 }
  9. }
复制代码
输出结果为6,而不是4或者7,可见赋值的最终结果参考左边。
回复 使用道具 举报
不明白为什么不写j++,搞出这多问题。
回复 使用道具 举报
果然反编译才是王道啊,编译器底层怎么干的,各个厂商估计都不一样,所以我们写代码应该尽量避免写出这种代码。。不过作为学习真是不错,受教了。
回复 使用道具 举报
本帖最后由 袁錦泰 于 2012-5-22 12:07 编辑
云惟桉 发表于 2012-5-22 11:54
1121411378

826288180 你拒绝被添加好友....
回复 使用道具 举报
袁錦泰 发表于 2012-5-22 11:53
哥们儿留个QQ号...

1121411378
回复 使用道具 举报
云惟桉 发表于 2012-5-22 11:43
嗯,貌似看懂了这个对编程很有帮助。不过先把基础打好最要紧,现在最担心就是基础不牢靠,做事时事倍功半 ...

哥们儿留个QQ号...
回复 使用道具 举报
袁錦泰 发表于 2012-5-22 10:51
非常感謝!! 我也看不懂,想和你取取經,這東西似乎對程序分析非常有幫助...

嗯,貌似看懂了这个对编程很有帮助。不过先把基础打好最要紧,现在最担心就是基础不牢靠,做事时事倍功半。要盖高楼,还是需要稳固的地基啊~
回复 使用道具 举报
j的值没有变化,如果++在前,结果就是100了,因为++在后,所以在将j赋给j后,j 再自增的值没有赋给谁,仍为0
回复 使用道具 举报
云惟桉 发表于 2012-5-22 00:47
我知道的有两种方式,再多的就不知道了
我用的是【javap -c 类名 】的命令,实际上这是一个反汇编过程。
...

非常感謝!! 我也看不懂,想和你取取經,這東西似乎對程序分析非常有幫助...
回复 使用道具 举报
袁錦泰 发表于 2012-5-21 22:54
哥們,請教個問題,你上面的反編譯結果是怎麼的出來的?

我知道的有两种方式,再多的就不知道了
我用的是【javap -c 类名 】的命令,实际上这是一个反汇编过程。
另外一种方式是在eclipse里装jadclipse。
我对这个不是很在行,而且有些反汇编的指令我看不懂,是舍友帮忙看的。
希望能帮助你~
回复 使用道具 举报
云惟桉 发表于 2012-5-21 19:48
下面是用javap -c 来反编译成汇编,查操作过程。
j++反编译结果:
public static void main();

哥們,請教個問題,你上面的反編譯結果是怎麼的出來的?
回复 使用道具 举报
j=j++;
System.out.println(j);
实际上是先输出j,然后再进行++运算。无论你的for循环是什么样的,他输出的永远是j的初始值0;
把j++换成++j,最终结果就是100。因为他是先进行++运算,然后将运算完的结果再进行输出;
回复 使用道具 举报
郭宁 发表于 2012-5-21 20:50
按你的意思   j=j++  这种情况 j 在运算的过程  一直是被 置为 1  又 置为 0 这样循环的么?
  ...

j=0
for..{
j=j++
}
每次循环的时候,先进行赋值运算j=0,再进行自增运算++,但是此时并没有任何变量记住这个自增的后的变量,所以下次循环的时候j还是0,如此循环100次,最终还是j还是0.
回复 使用道具 举报
郭宁 发表于 2012-5-21 20:50
按你的意思   j=j++  这种情况 j 在运算的过程  一直是被 置为 1  又 置为 0 这样循环的么?
  ...

Excellent!!!说明楼主已经理解了!
回复 使用道具 举报
郭宁 中级黑马 2012-5-21 20:50:34
9#
云惟桉 发表于 2012-5-21 20:37
嗯,楼主可以这么理解:(假设b=0)
step 1:  b的值压栈,栈内为0;
step 2:  b++,此时b=1;

按你的意思   j=j++  这种情况 j 在运算的过程  一直是被 置为 1  又 置为 0 这样循环的么?
回复 使用道具 举报
郭宁 发表于 2012-5-21 20:30
按你的思路想 感觉是那么回事,但还是有些迷糊,不清楚为什么这样紫~
引用Fc10232的“打比方 a = b++”  ...

嗯,楼主可以这么理解:(假设b=0)
step 1:  b的值压栈,栈内为0;
step 2:  b++,此时b=1;
step 3: 数据出栈,0出栈,赋值,a=0;
这样楼主理解吗?
不理解可以使用输出语句,输出a和b,可能对理解有点帮助
回复 使用道具 举报
郭宁 中级黑马 2012-5-21 20:30:23
7#
云惟桉 发表于 2012-5-21 19:48
下面是用javap -c 来反编译成汇编,查操作过程。
j++反编译结果:
public static void main();

按你的思路想 感觉是那么回事,但还是有些迷糊,不清楚为什么这样紫~
引用Fc10232的“打比方 a = b++” 能给我详细说一下 整个赋值过程么?
回复 使用道具 举报
java虚拟机的机制与C的不同,同样的程序在C语言中 如下:
  1. #include<stdio.h>
  2. void main()
  3. {
  4.         int i; int j=0;
  5.         for(i=0;i<100;i++)
  6.            j=j++;
  7. printf("%d",j);
  8. }
复制代码
结果为100
我查阅了有关资料 得出下面的回答
What happens is that the initial value of x is stored in a temporary register, then x is incremented, then the value stored in the register is asigned to the left hand side of the expression, in this case the LHS is x so x gets its original value.
int x = 0;
x = x++;
Steps:
1 initial value of x is stored in temp register. So temp = 0.
2 x is incremented. x = 2 and temp = 0.
3 the value of the temp register is assigned to the LHS. x = 0

我翻译下,
程序运行中,x的起始值被存在了一个暂时的寄存器中,然后那个原始的x自增1,然后寄存器中的x值给了表达式的等号左边,所以x的值总是原始的。

如果楼主想进一步研究,可以借助反编译,有下面的链接
http://zhidao.baidu.com/question/392618024.html

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
下面是用javap -c 来反编译成汇编,查操作过程。
j++反编译结果:
public static void main();
  Code:
   0:   iconst_0
   1:   istore_0
   2:   iload_0
   3:   iinc    0, 1
   6:   istore_0
   7:   return
}
++j 反编译结果:
public static void main();
  Code:
   0:   iconst_0
   1:   istore_0
   2:   iinc    0, 1
   5:   iload_0
   6:   istore_0
   7:   return
}
return前一句istore_0的意思是出栈。数据出栈也就意味着将最终结果赋值给左边变量。
因此重要的结论是:赋值操作总是在最后执行的!
所以并不要理所当然的按某些教材书上理解,什么++j在赋值前完成自增,j++在赋值后完成自增。这些都是不明确的结论。
实际是:
对于j=++j :先将j 的值自增然后压栈,最后赋值的时候出栈取出数值进行传递。
对于j=j++ :先将j 的值压栈,然后j++,最后把原来j 的值出栈进行赋值。因此还是原来的j 值。

不知道我这么说,楼主是否理解了。要记得赋值操作是最后的出栈操作。
希望能帮到你

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马