关于java和c++中的i++
看到一个题目,大概是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++自增的文章,
其中,有这样一段代码,
#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++的更多相关文章
- JAVA WEB项目中各种路径的获取
JAVA WEB项目中各种路径的获取 标签: java webpath文件路径 2014-02-14 15:04 1746人阅读 评论(0) 收藏 举报 分类: JAVA开发(41) 1.可以在s ...
- 揭开Java IO流中的flush()的神秘面纱
大家在使用Java IO流中OutputStream.PrintWriter --时,会经常用到它的flush()方法. 与在网络硬件中缓存一样,流还可以在软件中得到缓存,即直接在Java代码中缓存. ...
- JAVA安装过程中出现的“javac不是内部或外部指令”的解决方法
近来重新安装了JAVA,安装过程中出现问题,网上找到解决办法,汇总发布. 解决流程: 1.确定自己的环境变量设置没问题,没有出现遗漏 : . 等情况 (具体环境变量设置百度) 2.环境变量设置后 ,d ...
- Java Web开发中MVC设计模式简介
一.有关Java Web与MVC设计模式 学习过基本Java Web开发的人都已经了解了如何编写基本的Servlet,如何编写jsp及如何更新浏览器中显示的内容.但是我们之前自己编写的应用一般存在无条 ...
- Java EE 编程中路径
版权声明:未经博主允许,不得转载 首先我们要限定一个范围,是一个项目,或是以个访问地址..就先以一个项目为限定的范围 前述: 学过物理学的都知道相对运动和绝对运动, 虽然是相似的概念,但这里的要简单得 ...
- 【java】jackson 中JsonFormat date类型字段的使用
为了便于date类型字段的序列化和反序列化,需要在数据结构的date类型的字段上用JsonFormat注解进行注解具体格式如下 @JsonFormat(pattern = "yyyy-MM- ...
- Java线程并发中常见的锁
随着互联网的蓬勃发展,越来越多的互联网企业面临着用户量膨胀而带来的并发安全问题.本文着重介绍了在java并发中常见的几种锁机制. 1.偏向锁 偏向锁是JDK1.6提出来的一种锁优化的机制.其核心的思想 ...
- [转]java去除List中重复的元素
java去除List中重复的元素 如果用Set ,倘若list里边的元素不是基本数据类型而是对象, 那么请覆写Object的boolean equals(Object obj) 和int ...
- [Liferay6.2]启动Tomcat提示APR不能在java类库路径中被找到的解决办法
问题描述 启动liferay之后,在控制台中打印出会打印出以下信息: 信息: The APR based Apache Tomcat Native library which allows optim ...
- Java在ACM中的应用
Java在ACM中的应用 —. 在java中的基本头文件(java中叫包) import java.io.*; import java.util.*; //输入Scanner import java. ...
随机推荐
- mysql命令参数详解
一,MySQL命令行参数 Usage: mysql [OPTIONS] [database] //命令方式 -?, --help //显示帮助信息并退出 -I, --help //显示帮助信息并退出 ...
- flask-mail发送QQ邮件代码示例(亲测可行)
from flask import Flask from flask_mail import Mail, Message app = Flask(__name__) app.config.update ...
- instance 怎么获得自己的 Metadata - 每天5分钟玩转 OpenStack(169)
要想从 nova-api-metadata 获得 metadata,需要指定 instance 的 id.但 instance 刚启动时无法知道自己的 id,所以 http 请求中不会有 instan ...
- 20155323 2016-2017-2 《Java程序设计》第5周学习总结
20155323 2016-2017-2 <Java程序设计>第5周学习总结 教材学习内容总结 异常处理 提供两种异常处理机制:捕获异常和声明抛弃异常. 捕获异常:在Java程序运行过程中 ...
- 程序员的基本功之Java集合的实现细节
1.Set集合与Map 仔细对比观察上面Set下和Map下的接口名,不难发现它们如此的相似,必有原因 如果只考察Map的Key会发现,它们不可以重复,没有顺序,也就是说把Map的所有的Key集中起来就 ...
- 老李分享:Web Services 架构 2
服务传输层 这一层负责应用之间的消息传输.目前,该层包括了超文本传输协议(HTTP).简单邮件传输协议(SMTP).文件传输协议(FTP).以及一些新兴协议,比如块可扩展交换协议(BEEP). XML ...
- Oracle的基本学习(二)—基本查询
一.基本查询语句 (1)查看当前用户 show user; (2)查看当前用户下的表 select * from tab; (3)查看员工表的结构 desc emp; (4)选择全部列 S ...
- 在ElasticSearch中使用 IK 中文分词插件
我这里集成好了一个自带IK的版本,下载即用, https://github.com/xlb378917466/elasticsearch5.2.include_IK 添加了IK插件意味着你可以使用ik ...
- 利用原生JS判断组合键
<script type="text/javascript"> var isAlt = 0; var isEnt = 0; document.onkeydown = f ...
- 基于51单片机IIC通信的PCF8591学习笔记
引言 PCF8591 是单电源,低功耗8 位CMOS 数据采集器件,具有4 个模拟输入.一个输出和一个串行I2C 总线接口.3 个地址引脚A0.A1 和A2 用于编程硬件地址,允许将最多8 个器件连接 ...