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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 神之梦 金牌黑马   /  2013-5-13 13:24  /  1941 人查看  /  18 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 神之梦 于 2013-5-13 16:00 编辑

就这段小代码:

  int a=3,b;
   a=a++;
   System.out.println(a);
   b=a++;
   System.out.println(a);

运行结果是:3   4

我想知道第一个输出结果为什么是   3   ?

对于自增的运算我懂,想不明白的是我将a++赋值给a,为什么a++感觉就没自加了??导致结果还是3,而我将a++赋值给b,结果却为了4了,想知道哪个地方的原因???

评分

参与人数 1技术分 +1 收起 理由
殇_心。 + 1

查看全部评分

18 个回复

倒序浏览
a=a++是a先把原来的值赋给了a,然后啊再自增。当执行到b=a
++的时候a的值是4了,这时a把4赋给了b,a再自增

评分

参与人数 1技术分 +1 收起 理由
殇_心。 + 1

查看全部评分

回复 使用道具 举报
因为你打印的第一个a++是 自增后的a也就是3,你打印的第二个a++是 a自增一次后的也就是4.你再第三次打印的话 就是5了。 a++的++写在a后面就是先赋值再自增。 你第一次a++虽然自增了,但是赋值是在自增之前。想要看到自增的效果得下一次赋值。

评分

参与人数 1技术分 +1 收起 理由
殇_心。 + 1

查看全部评分

回复 使用道具 举报
a++ 实际上是三行代码:
   a=3;
   4=3+1;
   a=4;
而++a 实际上是一行代码:
   a=a+1;
具体为什么,估计要反汇编一下才知道了
回复 使用道具 举报
潘贵 发表于 2013-5-13 13:38
a=a++是a先把原来的值赋给了a,然后啊再自增。当执行到b=a
++的时候a的值是4了,这时a把4赋给了b,a再自增 ...

先赋给a,然后不也自增了么,怎么还是3?
回复 使用道具 举报
王靖远 发表于 2013-5-13 13:39
因为你打印的第一个a++是 自增后的a也就是3,你打印的第二个a++是 a自增一次后的也就是4.你再第三次打印的 ...

我测试了下打印第三次,结果是4,不是5,原因可能也不是这样的
回复 使用道具 举报
崔宏奎 发表于 2013-5-13 13:45
a++ 实际上是三行代码:
   a=3;
   4=3+1;

汇编忘得很干净了,忘大神帮我看下怎么回事
回复 使用道具 举报
白磊 中级黑马 2013-5-13 14:25:29
8#
  int a=3,b;
   a=a++;
   System.out.println(a);               第一次a++运算之后,本次输出的a的值还是a;但是当他在下一次使用的时候a的值才会加1;这时a=4;
                                                也就是在下面b=a++;这一句其实也是把a先赋值给b,所以b=4;如果在下一次使用到a,a的值就是5了。
   b=a++;
   System.out.println(a);

回复 使用道具 举报
当你执行a=a++时,先将静态变量a的值赋给变量a,则打印出的a就等于静态变量a的值3,然后静态变量a再自加1,变成了4;
当你执行b=a++时,把静态变量a的值赋给变量b,因为上一步静态变量a的值变成了4,,所打印出的b就等于静态变量的值4,然后a再自加1。
a++:先赋值,然后再自加1。
++a:先自加1,然后再赋值。
回复 使用道具 举报

   a=a++;  
++在后面,运算完毕自增一次, 意思就是 ,把a 赋给 a  打印了之后,a自增了一次 。所以打印a是3
   b=a++;
当打印完毕之后,a自增了一次,就是4了,然后运算,完事再打印a的时候就是4了,如果还有下次赋值动作的话,a就是5了

不知道这么说能否懂?语言组织的不好
回复 使用道具 举报
神之梦 发表于 2013-5-13 14:15
我测试了下打印第三次,结果是4,不是5,原因可能也不是这样的

int a=3,b;
   a=a++;//先是把a赋值给a,然后a第一次自增
   System.out.println(a);//打印出来是a的值
   b=a++;//把第一次自增后的a值赋值给b,然后a第二次自增
   System.out.println(a);//打印出来的是a第一次自增后的a值
  b=a++;//把a第二次自增后的a值赋值给b,然后a第三次自增
System.out.println(a);//打印出来的是a第二次自增后的a值。


这样写明白了吗?
回复 使用道具 举报

RE: 自增运算符遇到的一个小问题

神之梦 发表于 2013-5-13 14:11
先赋给a,然后不也自增了么,怎么还是3?

a被赋值在栈内存中,a++在方法区中,当a没有被调用时(打印个人认为不算是调用),栈中的值是3,当被调用时方法区中运算出的值再赋给a

个人理解,不一定对,希望相互进步
回复 使用道具 举报
这个我也知道 哈哈
视频里面老师不是讲了的吗
a++和++a不一样  
a++在后面 举例说先跟别人玩再吃饭,
++a是先吃饭再跟别人玩
所以开始a=a++ 先赋值给a再自增 所以打印是3  然后它自增变为4
下面一样,b=a++ 先把a现在的值 是4赋给b  b打印出来当然是4.
然后再自增 现在的a是5了。你再加一条语句打印a看看是否为5
回复 使用道具 举报

RE: 自增运算符遇到的一个小问题

神之梦 发表于 2013-5-13 14:11
先赋给a,然后不也自增了么,怎么还是3?

a被赋值在栈内存中,a++在方法区中,当a没有被调用时(打印个人认为不算是调用),栈中的值是3,当被调用时方法区中运算出的值再赋给a

个人理解,不一定对,希望相互进步
回复 使用道具 举报
王靖远 发表于 2013-5-13 14:58
int a=3,b;
   a=a++;//先是把a赋值给a,然后a第一次自增
   System.out.println(a);//打印出来是a的值

结合9楼动态变量的理解,加上哥们的解释算是清楚了,我测试第三次打印的时候没有再经过运算的,哥们的意思是要再进行一次运算才会得到5
回复 使用道具 举报
潘贵 发表于 2013-5-13 15:43
a被赋值在栈内存中,a++在方法区中,当a没有被调用时(打印个人认为不算是调用),栈中的值是3,当被调用 ...

感谢哥们,对于内存方面我还没理解到,不过我想你的理解是对的
回复 使用道具 举报
long 中级黑马 2013-5-13 16:13:53
17#
本帖最后由 long 于 2013-5-13 16:15 编辑

我给楼主说得详细点:
int a = 3, b;
a = a++;
是将表达式a++的值赋给a, 但表达式a++的值是3,因此a = 3。自增运算符分两种:前自增(++位于变量名前面)和后自增(++位于变量名后面)。前自增表示先自增,再用自增后的变量计算表达式的值,后自增表示先用自增前的变量计算表达式的值,再自增变量。a = a++; 的效果相当于int  t = a++; a = t; 。因为a = 3, 且是后自增,所以表达式a++的值是3,故 t = 3,  而a = t显然使得a = 3。在此过程中a++其实是自增的,只不过自增后又将自增前的值赋给a,所以a++感觉就没自加了。
在将a++赋给b的过程中,a显然自增了一次,a自增后的值当然是4,但b等于a自增前的值,即b = 3。
回复 使用道具 举报
本帖最后由 崔宏奎 于 2013-5-13 16:33 编辑

由于没有反汇编过JAVA,就反汇编了一下C语言的,先贴源码(有一行发现打错了。。。郁闷,不过不影响):


反汇编了一下(为了能看明白,我加了些注释,并划分了五个区域):


从第二个区域可以看出,其实a已经从3变为了4,只不过,还没有使用,就已经被原来的值覆盖了
  1. INC     DWORD PTR [EAX]                 ;变量a = a + 1
  2. MOV     DWORD PTR [EBP-4], EDX          ;将EDX的值(EDX=3)放入变量a的地址
复制代码
那么到底是为什么,我决定做一下实验,首先想到了会不会是a=a++;与a=++a;不同导致的。
为了对照一下"a=a++" 与 "a=++a"区别在哪里,我重新修改了一下代码:


可以看出代码【3】与这一段的区别:
b=a++;的执行如下:
1.取出a的值,放在一个临时变量里(int temp = a;)
2.a自增(a = a + 1;)
3.将临时变量的值,传给b(b = temp;)

而b=++a;的执行如下:
1.a自增(a = a + 1;)
2.将a的值,传给b(b = a;)

那么,对照以上两点,再来看a = a++,由于是后置的自增,应该参照第一个方式:
猜测:
1.取出a的值,放入临时变量(temp = a;)
2.a自增(a = a + 1;)
3.将临时变量的值,传给a(a = temp;)

实际(代码段【2】,就不贴了)

猜测 == 事实
研究结束。
回复 使用道具 举报
崔宏奎 发表于 2013-5-13 16:23
由于没有反汇编过JAVA,就反汇编了一下C语言的,先贴源码(有一行发现打错了。。。郁闷,不过不影响):

哥们果然是大神,汇编和c也学得如此之好,我想那个temp应该就是java中给a分配存储的临时内存或者地址之类的东东。经过这么多哥们的分析,小弟我也差不多明白了,辛苦了哥们!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马