黑马程序员技术交流社区

标题: 为什么这个a++,没有运行? [打印本页]

作者: 马磊    时间: 2012-10-12 21:32
标题: 为什么这个a++,没有运行?
本帖最后由 马磊 于 2012-10-12 23:35 编辑

被一道简单的题目难住了:
int a=1;
a=a++;
System.out.println(a);


本来以为结果 是2呢,但是输出的是1。a++到底运行了没有,为什么这里的a++没有改变a的值?多谢!

作者: 徐梦侠    时间: 2012-10-12 21:46
因为a++运行加1会在赋值之后进行,相当于最后a还是等于1.其实你完全可以直接这样写:
被一道简单的题目难住了:
int a=1;
a++;
System.out.println(a);
作者: yangfengxiao    时间: 2012-10-12 21:51
准确的说,++称作递增运算符,并且

1. 放在变量左边叫前置递增运算符,它在变量被引用前先让变量产生递增(即加一),再将递增后的值代入表达式进行计算。

2. 放在变量右边叫后置递增运算符,它在变量被引用后才让变量产生递增(即加一),即将递增前的值代入表达式进行计算。

举例:
int a = 0;
int b = ++a;// a先递增,结果a=1, b=1

int x = 0;
int y = x++;// a先代入表达式计算,再递增,结果y=0, x=1
作者: 马磊    时间: 2012-10-12 21:54
徐梦侠 发表于 2012-10-12 21:46
因为a++运行加1会在赋值之后进行,相当于最后a还是等于1.其实你完全可以直接这样写:
被一道简单的题目难住 ...

不对,你这样写的结果是2。刚才验证过了,但是还是不理解为什么会不一样。
作者: 马磊    时间: 2012-10-12 22:03
yangfengxiao 发表于 2012-10-12 21:51
准确的说,++称作递增运算符,并且

1. 放在变量左边叫前置递增运算符,它在变量被引用前先让变量产生递增 ...

多谢你的解释。但是a把1的值赋给a之后,它应该又自加了1,为什么最后显示的结果不是2?
作者: 熊志伟    时间: 2012-10-12 22:03
a++可以理解为先用再加,而++a可以理解为先加再用,也就是说,a++的值是a加1之前的值,而++a的值是a加1之后的值
我之前也纠结了半天,其实把毕向东老师的初级视频基础第二天09多看几篇后就明白了,里面讲的很清楚
作者: yangfengxiao    时间: 2012-10-12 22:08
马磊 发表于 2012-10-12 22:03
多谢你的解释。但是a把1的值赋给a之后,它应该又自加了1,为什么最后显示的结果不是2? ...

那我用张孝祥老师java基础课本上的原句跟你解释下吧,++a是变量a在参与恰运算之前先将自己加1后,再用新的值参与其他运算,而a++是先用原来的值参与其他运算后,再将自己加1.
作者: 马磊    时间: 2012-10-12 22:10
熊志伟 发表于 2012-10-12 22:03
a++可以理解为先用再加,而++a可以理解为先加再用,也就是说,a++的值是a加1之前的值,而++a的值是a加1之后 ...

a = a++; 这里先把a的值,也就是1赋给a,然后再加1,但为什么结果显示a的值是1,不是2?
我很怀疑这里的a++到底运行了没有
作者: 马磊    时间: 2012-10-12 22:12
yangfengxiao 发表于 2012-10-12 22:08
那我用张孝祥老师java基础课本上的原句跟你解释下吧,++a是变量a在参与恰运算之前先将自己加1后,再用新 ...

“再将自己加1”,为什么这里的结果不是1+1,而是没有加1之前的1?
作者: 胡斌    时间: 2012-10-12 22:20
记住:a++是个表达式,表达式的值不变。
作者: 马磊    时间: 2012-10-12 22:33
胡斌 发表于 2012-10-12 22:20
记住:a++是个表达式,表达式的值不变。

我是这样理解的:
a=a++;
先把a原来的值1赋给a,这个时候a是1,然后a再自加1,在输出的时候不是应该为2 了吗?
作者: yangfengxiao    时间: 2012-10-12 22:35
马磊 发表于 2012-10-12 22:12
“再将自己加1”,为什么这里的结果不是1+1,而是没有加1之前的1?

a=a++是先把右边a原来的值赋给左边的a,再把右边a的值加1.我感觉你把左边的a和右边的a的值弄混了,你可以把左右两边的变量定义的不一样,例如: int a=1;int b=a++;   此时b的值为1而a的值为2.
作者: 马磊    时间: 2012-10-12 22:45
yangfengxiao 发表于 2012-10-12 22:35
a=a++是先把右边a原来的值赋给左边的a,再把右边a的值加1.我感觉你把左边的a和右边的a的值弄混了,你可以 ...

可能是我没说清楚。
我知道a=a++,这一句是先把a原来的值赋给了a,就是1,但是这之后应该还有一个a自加1的过程,为什么System.out.println(a),这一句里面的a还是1,而不是a加1以后那个值?
作者: 焦志鹏    时间: 2012-10-12 22:52
首先说,a=a++ 这种写法本身就是不规范的,至少我没见过这么写的...

如果只是想理解下这句话的意思的话,a++是先赋值给等号左边的变量,然后加一,所以先打印的是a原来的值;
作者: 范泰洋    时间: 2012-10-12 22:54
兄弟,给个我弄的图解。你看看这个能不能解决的你的疑惑兄弟,给个我弄的图解。你看看这个能不能解决的你的疑惑

i .png (297.88 KB, 下载次数: 129)

i  .png

作者: 谭立文    时间: 2012-10-12 22:59
int a = 1;
m = a++;  m =  1 因为a++是先赋值然后再自增
a = a++;   a = a++ 和 a = m 效果是一样的
作者: 马磊    时间: 2012-10-12 23:00
看了崔老师的视频,发现了问题所在,原来一直都理解错了。只知道a++是赋值后自加1,其实在内存里不是这样的。
先说一般情况下 :
例如 int b=a++;此语句会先在内存空间中创建一个b的区域,然后把a的值放入到一个临时空间,然后a的值自加1,然后再把临时空间里的值放到b中去。这时候b的值还是原来a的值,而a已经是加1后的值了,所以通俗说法是先赋值后++;
在这道题里,a=a++,同样分析一下是:a先把自己的值放到一个临时空间里,然后a再自加1,然后(这里就是问题所在了)临时空间里a原来的值又赋值给了a,所以a还是原来的值。因此是有a+1的过程的,不过后来被临时空间里原来的a值覆盖掉了。

作者: 马磊    时间: 2012-10-12 23:11
范泰洋 发表于 2012-10-12 22:54
兄弟,给个我弄的图解。你看看这个能不能解决的你的疑惑兄弟,给个我弄的图解。你看看这个能不能解决的你的 ...

这个图不错,谢谢兄弟!
作者: 范泰洋    时间: 2012-10-12 23:13
客气了。大家都是在一起奋斗中,就应该互相帮助的!
作者: 马磊    时间: 2012-10-12 23:14
受C语言的毒害了,因为C语言里没有临时空间这一说,因此就说a++是先赋值再加1,导致了对这道题的误解。
在C里面,a=a++;这句话的结果就是2,和Java不一样。
作者: yangfengxiao    时间: 2012-10-13 21:06
马磊 发表于 2012-10-12 22:45
可能是我没说清楚。
我知道a=a++,这一句是先把a原来的值赋给了a,就是1,但是这之后应该还有一个a自加1的 ...

奥,那你看看范泰洋给你的那个图,那个图画的非常不错。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2