关于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. ...
随机推荐
- JDBC调用存储过程的例子
下面是我学到了Oracle存储过程,在这里跟大家简单的分享一下利用JDBC调用存储过程的例子: 废话就不啰嗦,现在就直接上机代码. 首先我利用的是Oracle中默认的 scott 数据库里的 emp员 ...
- opencv配置(win10+VS2015+opencv3.1)
Step 1:准备工作 a.win10 b.vs2015 c.opencv3.1[从http://opencv.org/downloads.html下载] Step 2.开始安装 a. 双击openc ...
- CentOS 7 Root用户密码重置 2017-04-02
跨平台系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#linux 开机的时候按e (如果正在使用,你可以输入reboot,然后赶紧按回车键,也可 ...
- Lvs+keepalived+mysql主从热备
p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; f ...
- Mac 自定义sublime在浏览器中打开的快捷键/win系统理论通用
安装"view in browser"官方版的说明:(前提是得先安装package control插件) 1.通过"ctrl+shift+p"打开命令面板 2. ...
- CSS如何实现圆角的outline效果?
一.首先,outline是个很牛逼的东西 温故而知鑫,10年的时候写过一篇可用性方面的文章:“页面可用性之outline轮廓外框的一些研究”,还算挺有用的:3年之后,也就是13年,介绍了个没什么使用价 ...
- cmd输入svn提示svn不是内部或外部命令
已经安装了svn,但是在cmd中输入svn命令的时候提示svn不是内部或外部命令是因为没有安装svn client. 解决办法: windows安装svn的时候默认是不安装 svn comand li ...
- Android 学习笔记之实时保存数据-现场保护onSaveInstanceState()
数据保存:在软件开发中我们希望保存下各个Activity数据,以实现客户数据的时时保存,达到较好的用户体验. 那么我们需要解决如下问题: 1.什么时候保存? 2.保存哪些数据? 我想保存应用产 ...
- mysql 分析5语句的优化--索引添加删除
查看表的索引 show create table 表名; show index from 表名; show keys from表名; 添加索引 alter table 表名 add index 索 ...
- c++设计成员变量可动态调整的动态类结构
本文主要介绍一下如何使用c++设计成员变量可动态调整的抽象动态类结构.首先介绍一下项目中以前使用的一种类结构:静态类结构 1.静态类结构 很多时候,在项目开发中设计类结构时,我们往往有一种简单.直接的 ...