看到一个题目,大概是i=i++之类。

  乍一看很简单,都知道i++的先参与计算再自增,

  所以i不变。

  但是仔细一想,

  如果i不变,

  那么在赋值之后,

  自增的i,

  增加的是谁呢?

  逻辑顺序是怎样的呢?

//1.i=i++是这样的吗?;
int i=0,temp;//此处temp代表副本
i=0;
temp=i+1;//根据返回的值仍然为0判断,副本自增长,过了作用域,被GC回收了。 //2.还是这样的?
i=0;
i/*(此时i=1)*/=0/*(在执行i++过程中,改变了i的值,i=i+1,然而,i++返回运算前的副本,所以之前的自增被覆盖掉了)*/;

  查看了相关的文章关于i++的底层实现原理

  其中i=i++的描述是这样的

_temp = i;  

i = i + 1;  

i = _temp;

  

  符合第二种猜想。

  仔细想想,

  使用i++时,

  会直接影响i的值,

  所以不太可能对副本进行自增。

  i++的逻辑顺序应该是获取i,复制i,对i进行自增,返回i的副本。

public int add(int i){
int temp=i;
i=i+1;
return temp;
}

在查看这篇文章时,

  看到了另外一篇基于C++自增的文章,

++i和i++ 以及其底层实现

  其中,有这样一段代码,

#include <iostream>
using namespace std; int main()
{
int i = 100;
i += (i++);
cout << i << endl; i = 100;
i += (++i);
cout << i << endl; return 0;
}

  

  输出结果为:201

        202

  原因大概是因为自增时,i的值被改变了。

  开始也没多想,

  只是试着去java中运行一下,

  心里理所当然的认为结果应该是一致的。

public class ForTest {
public int add(int i){
int temp=i;
i=i+1;
return temp;
}
public static void main(String[] args) {
int i=100;
/*
* i=i+(i++);
* i(100)=100+(i++(100));
*
*/
i+=(i++);
System.out.println(i); i=100;
i+=(++i);
System.out.println(i); i=100;
/* 前一个i++返回i自增前的值,但是i的值被改变,i=101.
* 后一个i++也返回自增前的值,但是i此时的值已经是101,
* 所以返回101,其后i自增为102.
* 最后运算并赋值
* i=100+101;
* tips:括号不影响i++的优先级,仍然先参与计算,再进行赋值;
* */
i=(i++)+(i++);
System.out.println(i);
}
}

  结果是:200

      201

      201

  疑问:为什么会不同?

  思考:java和c++中,i的自增都是返回一个副本,

     jvm是用c和c++编写的,底层机制应该相同

     java的编译器是用java写的,编译的不同造成了不同结果。

c++中,i+=(++i)

i += 1; //100+1 = 101
i += i; //101+101 = 202

java中,i+=(++i)

i(1)=100;
i(2)=101;
i(101)=100+101;

    在c++中,运算时,直接从i相应的栈中取i,所以被改变的i马上被使用。

    在java中,运算时,虽然i被改变了,但是仍然作用不到之前的i,即在运算时,从上向下,从左向右,翻译成字节码。

    这又涉及到了所谓的编译型语言和解释型语言,

    参考了虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩

       

最新文章

  1. 用Swagger生成接口文档
  2. LVM 类型的 Storage Pool - 每天5分钟玩转 OpenStack(8)
  3. APUE第五章:标准IO库
  4. 将DataTable格式化为json字符串返回
  5. 瞧一瞧,看一看呐,用MVC+EF快速弄出一个CRUD,一行代码都不用写,真的一行代码都不用写!!!!
  6. header函数
  7. oracle必须启动的服务
  8. robotframework ride 版本兼容问题
  9. ECLIPSE IDEA 调音 1
  10. Go 从入门到精通(三)字符串,时间,流程控制,函数
  11. Quartz.NET的使用(附源码)
  12. golang社区
  13. Python实现基于协程的异步爬虫
  14. Codeforces Round #484 (Div. 2)Cut 'em all!(dfs)
  15. web.xml中Servlet4.0版本的头信息格式
  16. Windows7 Autoconfiguration IPv4 Address 导致无法上网
  17. 嵌入式Linux内时区配置
  18. innerHTML和 innerText的区别
  19. Visual Studio 2019/2017 安装使用教程(快速上手版)
  20. Swift10大开源项目记录

热门文章

  1. 学习手机端的META差异,打造自己的移动网页
  2. deepin系统下如何设置wifi热点(亲测有效)
  3. [编织消息框架][JAVA核心技术]jdk动态代理
  4. win7禁用离开模式,让笔记本卡盖后进入休眠
  5. MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ...
  6. C语言指针基础
  7. 将一个对象push到数组之中的几点问题
  8. Python之路-计算机基础
  9. React Native 导入原生Xcode项目总结与记录
  10. Java并发编程:线程的基本状态