看到一个题目,大概是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,即在运算时,从上向下,从左向右,翻译成字节码。

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

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

       

关于java和c++中的i++的更多相关文章

  1. JAVA WEB项目中各种路径的获取

    JAVA WEB项目中各种路径的获取 标签: java webpath文件路径 2014-02-14 15:04 1746人阅读 评论(0) 收藏 举报  分类: JAVA开发(41)  1.可以在s ...

  2. 揭开Java IO流中的flush()的神秘面纱

    大家在使用Java IO流中OutputStream.PrintWriter --时,会经常用到它的flush()方法. 与在网络硬件中缓存一样,流还可以在软件中得到缓存,即直接在Java代码中缓存. ...

  3. JAVA安装过程中出现的“javac不是内部或外部指令”的解决方法

    近来重新安装了JAVA,安装过程中出现问题,网上找到解决办法,汇总发布. 解决流程: 1.确定自己的环境变量设置没问题,没有出现遗漏 : . 等情况 (具体环境变量设置百度) 2.环境变量设置后 ,d ...

  4. Java Web开发中MVC设计模式简介

    一.有关Java Web与MVC设计模式 学习过基本Java Web开发的人都已经了解了如何编写基本的Servlet,如何编写jsp及如何更新浏览器中显示的内容.但是我们之前自己编写的应用一般存在无条 ...

  5. Java EE 编程中路径

    版权声明:未经博主允许,不得转载 首先我们要限定一个范围,是一个项目,或是以个访问地址..就先以一个项目为限定的范围 前述: 学过物理学的都知道相对运动和绝对运动, 虽然是相似的概念,但这里的要简单得 ...

  6. 【java】jackson 中JsonFormat date类型字段的使用

    为了便于date类型字段的序列化和反序列化,需要在数据结构的date类型的字段上用JsonFormat注解进行注解具体格式如下 @JsonFormat(pattern = "yyyy-MM- ...

  7. Java线程并发中常见的锁

    随着互联网的蓬勃发展,越来越多的互联网企业面临着用户量膨胀而带来的并发安全问题.本文着重介绍了在java并发中常见的几种锁机制. 1.偏向锁 偏向锁是JDK1.6提出来的一种锁优化的机制.其核心的思想 ...

  8. [转]java去除List中重复的元素

    java去除List中重复的元素 如果用Set ,倘若list里边的元素不是基本数据类型而是对象, 那么请覆写Object的boolean   equals(Object   obj)   和int  ...

  9. [Liferay6.2]启动Tomcat提示APR不能在java类库路径中被找到的解决办法

    问题描述 启动liferay之后,在控制台中打印出会打印出以下信息: 信息: The APR based Apache Tomcat Native library which allows optim ...

  10. Java在ACM中的应用

    Java在ACM中的应用 —. 在java中的基本头文件(java中叫包) import java.io.*; import java.util.*; //输入Scanner import java. ...

随机推荐

  1. Vue.js 2.2 卡片api

    给vue开发者和爱好者发送点福利! 卡片上一共117个api,方便查阅 网址: https://vuejs-tips.github.io/cheatsheet Github: https://gith ...

  2. Maven项目搭建(二):Maven搭建SSM框架

    上一章给大家讲解了如何使用Maven搭建web项目. 这次给大家介绍一下怎么使用Maven搭建SSM框架项目. 首先我们来看一下pom.xml的属性介绍: project: pom的xml根元素. p ...

  3. Servlet过滤器和监听器知识总结(转)

    Servlet过滤器和监听器知识总结(转)  Servlet过滤器是 Servlet 程序的一种特殊用法,主要用来完成一些通用的操作,如编码的过滤.判断用户的登录状态.过滤器使得Servlet开发者能 ...

  4. reactjs点滴记录

    reactjs: render方法后面,}后面,不要加分号,加逗号,因为是对属性赋值,否则报错: var Test = React.createClass({ render:function(){re ...

  5. 利用php数组函数进行函数式编程

    因为一个BUG, 我在一个摇摇欲坠,几乎碰一下就会散架的项目中某一个角落中发现下面这样一段代码 这段程序与那个BUG有密切的关系. 我来回反复的捉摸这段代码, 发现这段代码实现了两个功能 第一个是在一 ...

  6. 2017携程Web前端实习生招聘笔试题总结

    考察encodeURI encodeURI(), decodeURI()它们都是Global对象的方法. encodeURI()通过将某些字符的每个实例替换代表字符的UTF-8编码的一个或多个转义字符 ...

  7. NestedScrollView嵌套RecycleView 滑动 实现上滑隐藏 下滑显示头部效果

    废了好大的劲才弄好的,记下来 方便以后查看 public class MainActivity extends AppCompatActivity { private RecyclerView mRe ...

  8. 20144306《网络对抗》CAL_MSF基础运用

    1  实验内容 一个主动攻击,如ms08_067 一个针对浏览器的攻击,如ms11_050 一个针对客户端的攻击,如Adobe 成功应用任何一个辅助模块 2  实验过程记录 2.1 主动攻击MS08- ...

  9. 使用VsCode编写和调试.NET Core项目

    ​ 本来我还想介绍以下VSCode或者donet core,但是发现都是废话,没有必要,大家如果对这个不了解可以直接google这两个关键字,或者也根本不会看我这边文章. ​ 好直接进入主题了,本文的 ...

  10. ES6 对let声明的一点思考

    说到ES6的let变量声明,我估计很多人会想起下面几个主要的特点: 没有变量声明提升 拥有块级作用域 暂时死区 不能重复声明 很多教程和总结基本都说到了这几点(说实话大部分文章都大同小异,摘录的居多) ...