关于Java中的自增、自减运算符j=j++;

期待可为 2014-03-28 07:39:41
这几天要准备找实习了,临阵磨枪,不快也光,然后开始疯狂做题突击,遇到了这么一题

import java.util.*;
public class Test{
public static void main(String[] args){
int j=0;
for (int i = 0; i < 100; i++){
j = j++;
}
System.out.println(j);
}
}

问输出的结果是多少。我相信很多人和我一样第一反应应该是想到100。但是结果却是错误的,不敢相信,然后上机实践发现确实不对。这是为什么?结果又应该是多少呢?
原来这是因为Java编译器使用了中间缓存变量的机制。j=j++;可以转换为如下写法:

temp = j;
j = j + 1;
j = temp;

这是在Java程序员面试宝典中给出的答案,感觉很不理解,然后又上网开始查,发现http://www.bitscn.com/plus/view.php?aid=20350这个解释就很容易理解了。
像j=j++;这种赋值语句, Java编译器每次遇到自增、自减运算符的时候都会开辟一块新的内存空间来保存赋值之前j的值,就是前文介绍的缓存变量,然后再将这个换成变量的值赋给左边的变量。链接里面通过内存空间图的方式讲解的很清楚,这里就不重复了。
所以本题的正确结果应该就是0。
题目会做错从本质上来分析的话应该还是对自增、自减运算符没掌握好,究竟是先用原值进行计算再加1,还是先加1再进行运算是这类题目特别需要注意的陷阱。这题是先用j的原值进行计算,那就是j=0;之后应该还有一个自增语句,但是由于变量已经被覆盖了,貌似就可以忽略了。
如果我们将赋值语句改为j = ++j;那会怎么样呢?现在应该是这么个流程

temp = j +1;
j = j + 1;
j = temp;

如果是这样的话,输出应该就是100了。
所以再对自增、自减运算符的变量进行赋值时都需要特别注意。借用别人的一句话:“如果在程序中只输入i++就不会出现这个方面的问题,所以大家在以后的程序中如果使用到i=i++的时候要格外小心,一般只需要用i++就不会有问题了。”
...全文
1776 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
期待可为 2014-04-02
  • 打赏
  • 举报
回复
引用 4 楼 litong534 的回复:
我也试过,同样很不理解,但是我想到了另一个问题。 你在for循环中用的是i++,如果按照上面的理解,i永远是0,永远到不了100的上限退出循环,那么for循环岂不是永远执行下去了?还是说for循环内部的算法和这个稍有不同?

int j=0; int i = 0;
int x = j++ + j++ + ++j;
int y = i++ + i++ + i++;
System.out.println("x:"+x+"y:"+y);
这两个赋值语句,x= 0(j++)+ 1(j++)+3(++j) = 4; y = 0(i++)+1(i++)+2(i++) = 3; 从另一个角度来看,i++操作具有一个延时效果,在本次计算的时候还是i原来的值,在下一次使用i值进行计算就是加1的结果;而++i不同,先在i原值的基础上加1,然后用更新后的i值参与计算。 上面对x赋值时,最后一个++j,上一步更新后的j为2,在此基础上+1参与计算记为3,所以最后结果为4; 对y赋值时,最后一个i++,用i的原值进行计算,之后i值更新,所以为3.
期待可为 2014-04-02
  • 打赏
  • 举报
回复
引用 4 楼 litong534 的回复:
我也试过,同样很不理解,但是我想到了另一个问题。 你在for循环中用的是i++,如果按照上面的理解,i永远是0,永远到不了100的上限退出循环,那么for循环岂不是永远执行下去了?还是说for循环内部的算法和这个稍有不同?
不是的,在遇到自增自减运算符以后会开拓一个新的内存空间,来保存i之前的值,由于没有发生赋值,则新保存的i值(i的旧值)就没用了,下一步直接舍弃,然后i本身是完成了加1运算的。
甜梅号 2014-03-31
  • 打赏
  • 举报
回复
这些面试题都是这样 看似很难理解 很炫 但其实实际工作都不可能用到这种个性的用法
  • 打赏
  • 举报
回复
我也试过,同样很不理解,但是我想到了另一个问题。 你在for循环中用的是i++,如果按照上面的理解,i永远是0,永远到不了100的上限退出循环,那么for循环岂不是永远执行下去了?还是说for循环内部的算法和这个稍有不同?
百曉生 2014-03-28
  • 打赏
  • 举报
回复
学习了 不过,一般不论是C还是Java,都不推荐这样使用自增
  • 打赏
  • 举报
回复
扫盲了

23,404

社区成员

发帖
与我相关
我的任务
社区描述
Java 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧