前言

  最近学习我在的团队招人,面试。我出了一道c的题。

int main(){
int i = ;
i+=++i;
printf("%d",i);
}

  别喷!今晚学长们说,java,c#中完全不同,我就千方百计试试。

i++ 的解释

  例子:

public class Test {

   public static void main(String[] args) {

     int i = 10;

     i = i++;

     System.out.println(i);

   }

}

  i = i++;则输出得到i=10;

  而如果同样的代码换成C/C++执行,则无论是i=i++;得到的结果是相同的,都是11,这是为什么呢?

其实就 i = i++;这个语句而言,其实很无聊,谁又会写这样一个语句呢(写错除外^_^),因为当你声明了 i = 0;后,要么你使用0,即直接使用i,要么你使用1,即用i++或者++i;没有必要写i=i++;所有这样的语句很无聊。但是正是这么个无聊的语句,引发了一个关于编译器编译机制的大问题的讨论!为什么java得到i=10;而C/C++得到的是11呢

这是由于Java和C/C++采用的编译器不同,编译器不同,所以编译机制也不同,大家可以通过javap命令反编译出java虚拟机指令例如如下一段程序:

public class Test {

   public static void main(String[] args) {

     int i = 0;

     i = i++;

     System.out.println(i);

   }

}

通过运行命令:javap –c Test  得到如下结果:

     

  对于上图中显示的结果大家可能读不懂,那么我在这里解释一下,从Code 0开始:0: iconst_0 //将int类型常量0压入栈(栈顶)

  这里大家可能会犯嘀咕,int i=0;i不是变量么?

  i 的确是变量,但赋值号后面的那个0是常量,可以这么说,对于基本数据类型的值(注意是值),都是常量。这区别于引用类型,比如Student   s = new  Student(); 赋值号后面的是一个对象,它是放在堆中的,而前面的这个s仍然是变量,是放在栈中的。

  如图:

    

  解释:

    1:istore_1 //将int类型值存入局部变量1

    2: iload_1//从局部变量1中装载int类型值。也就是说,这个时候把i变量中的值拿出来了,压入栈(栈顶),因为这里执行的是i++, 也就是先使用后++,所有这句的目的是想把i在++之前的值先找个地方保存起来。

    3:iinc 1,1// 把常量值1加到局部变量1上。这句话执行后i变量中存放的值就不是0了,而是1,注意:刚才压入栈的那个值,也就是i在++之前的值,即栈顶的值仍然是0

    6:istore_1//把栈顶的int类型的值存入变量1中。这句话就是用栈顶的0把i变量中的1给替换掉了。

 

 所以最后得出了i=0的结果。

用几句通俗易懂讲一遍

  Java在执行    变量=i++; 在执行变量赋值语句(不是常量赋值,而是例如:i = a;即赋值号后面有变量)之前,会先把i的值找个地方保存起来,然后直接在i变量的空间内对值+1,然后再把刚才保存起来的那个值赋给变量。

  那么清楚了上面的过程后,我们再来看看j=i++;的JVM指令:

       

过程是这样的:

    0:把int类型的常量0压入栈顶

    1:把栈顶int类型的值存入变量1中(即给i赋值为0)

    2:把int类型的常量0压入栈顶

    3:把栈顶int类型的值存入变量2中(即给j赋值为0)

    4:把变量1中的int类型的值装载到栈

    5: 把数值1加到变量1中(给i变量的值加1)

    8:把栈顶int类型的值存入变量2(即把0赋给j)

    所以,这时i的值为1,j的值为0

小结

所以大家在使用java中的i++时一定要注意,其他的没什么问题,只有i=i++;有问题,这和C/C++截然不同。

"i=i++"在java等高级语言的解释的更多相关文章

  1. Java路径操作具体解释

    1.基本概念的理解 绝对路径:绝对路径就是你的主页上的文件或文件夹在硬盘上真正的路径.(URL和物理路径)比如: C:\xyz\test.txt 代表了test.txt文件的绝对路径.http://w ...

  2. Java String类具体解释

    Java String类具体解释 Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,非常多时候,我们对它既熟悉又陌生. 类结构: public fin ...

  3. 设计模式 - 迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释

    迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考迭代器模式(ite ...

  4. “全栈2019”Java第九章:解释第一个程序

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. Java 序列化Serializable具体解释(附具体样例)

    Java 序列化Serializable具体解释(附具体样例) 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描写叙述的过程:反序列化deserializa ...

  6. 另外几种Java集合框架具体解释续

    另外几种Java集合框架具体解释续 作者:chszs,未经博主同意不得转载.经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs fastutil库优于Trove库的 ...

  7. 【Java面试题】解释内存中的栈(stack)、堆(heap)和静态存储区的用法

    Java面试题:解释内存中的栈(stack).堆(heap)和静态存储区的用法 堆区: 专门用来保存对象的实例(new 创建的对象和数组),实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型 ...

  8. Java中“指针”的解释以及对“引用”的理解

    Java中"指针"的解释以及对"引用"的理解 初学Java面对对象编程,对于一些概念还真的有点难以理解,主要是因为不由自主的联系到以前学过的C语言知识,时不时的 ...

  9. JAVA与编译语言及解释语言的关系

    转自JAVA结合了编译和解释执行的优点 编译型语言是一次性编译成机器码,脱离开发环境独立运行,所以运行效率较高,但是由于编译成的是特定平台上机器码,所以可移植性差. 编译型语言的典型代表有C.C++. ...

随机推荐

  1. asp.net core web 项目附加进程调试

    之前asp.net web项目在部署IIS站点的时候可以直接选择项目目录,不用发布,然后附加进程的时候,找到w3wp.exe开头的进程,再根据用户名找到要附加的进程,就可以附加进程调试了.但asp.n ...

  2. 人力资源项目中 add_account.php

    add_account.php ( 文件浏览 ) <?phpinclude('db_con.php');   if(isset($_POST['save'])) {    $employee_i ...

  3. python简单入门

    一. 初识python. 1. 认识计算机 CPU(大脑) 3GHZ + 内存(DDR4) + 主板 + 电源(心脏)+ 显示器 + 键盘 +鼠标+ 显卡 + 硬盘 80MB/s 操作系统 windo ...

  4. 第五周助教工作总结——NWNU李泓毅

    第五周助教总结 注:因第四次实验安排两个标准时间完成,因此本周未提交完整作业. 本周心得: 第四次实验进行过半,八组同学都在实验课上进行了一次中期总结,并形成书面总结在微信群中讨论. 根据各组同学的中 ...

  5. python random库

    random模块 >>> import random #随机小数 >>> random.random() # 大于0且小于1之间的小数 0.766433866365 ...

  6. Flask web 开发出现错误:TypeError: Allowed methods have to be iterables of strings, for example: @app.route(..., methods=["POST"])

    没有发现普通都语法错误,然后一一比对官方教程里面的代码,发现是在“@bp.route('/<int:id>/delete', methods=('POST'))”这一行代码里面method ...

  7. xx系统属性分析

    在本周的课程学习当中,我们简单了解到系统的一些属性,同时在课下也对<大型网站技术架构:核心原理与案例分析>进行了初步的阅读. 在书籍中我看到了许多其他的知识,也对课堂学习的知识有了巩固,现 ...

  8. verilog HDL-参数型数据对像 与‘define

    参数新数据对象是用来定义常量的,它可以提升verilog hdl代码的可读性和维护性. verilog hdl支持参数有两种,普通参数和局部参数.普通参数在模块例化时可以从新赋值,局部参数在模块例化时 ...

  9. [转] KVM scalability and consolidation ratio: cache none vs cache writeback

    http://www.ilsistemista.net/index.php/virtualization/43-kvm-scalability-and-consolidation-ratio-cach ...

  10. 背水一战 Windows 10 (93) - 选取器: FileOpenPicker, FolderPicker, FileSavePicker

    [源码下载] 背水一战 Windows 10 (93) - 选取器: FileOpenPicker, FolderPicker, FileSavePicker 作者:webabcd 介绍背水一战 Wi ...