`

有关i=i++;的讨论(转载)

阅读更多

[精彩] i = i++;


http://www.chinaunix.net 作者:bysea51  发表于:2009-07-02 22:44:30
发表评论】【查看原文】【Java讨论区】【关闭
<!-- 正文begin -->

public static void main(String[] args){
int i = 0;
i = i ++;
System.out.println("i = " + i);
}

我想问的是为什么输出的结果是
i = 0

就算是先执行“i = i”,可是i 的自加不还是要执行的吗?



 pause 回复于:2004-10-22 10:04:11

i++ 表达式的值是0.
你把i++的表达式的值赋给了i
那你说i的值是多少呢???


 demon-duke 回复于:2004-10-22 10:15:17

这个问题很有意思
你可以去看看编译以后的字节码
看看它是怎么个执行顺序


 sakulagi 回复于:2004-10-22 10:22:18

如果用i++和++i的话可以看到编译后的bytecode里iinc和iload的顺序不同。


 bysea51 回复于:2004-10-22 16:32:34

十分感谢大家,我用javap看了,不管是i = i++;还是i = ++i;其后都有一个istore_1,是用来赋值的吧,对于i++来说堆栈中的0一直都没改过,所以一执行istore_1,就把i的自加给毁了。


 demon-duke 回复于:2004-10-22 17:30:00

javap是什么东东?


 ilcj 回复于:2004-10-22 19:35:31

javap是一个Java类分解工具。它能够将一个类分解为一个字节码的描述,在这些描述中告诉了你在没有进行实际的反编译类之前的一个实现是什么样的。和javac不同,javap使用class文件而不是源文件。


 天下幽思 回复于:2004-10-24 18:12:17

这个是不是Java本身的BUG。
istore_1是什么意思,出现了两次。


 天下幽思 回复于:2004-10-24 18:31:15

我明白了。
i=i++;
i++执行的结果在istrore_1中,(是不是这样,请指教)
由于有关“i ”的操作没有了。所以没有再次iload
就是说变量“i”的内存空间里面没有立即改变。
这么解释的话,JAVA似乎有BUG啊。


 镖师甲 回复于:2004-10-24 20:26:30

i++的情况
iconst_0
istore_1
iload_1
iinc 1,1
istore_1

++i的情况
iconst_0
istore_1
iinc 1,1
iload_1
istore_1


 镖师甲 回复于:2004-10-24 20:29:51

从上边来看只有iload_1和iinc 1,1是颠倒的.我怎么没体会到为什么i++的时候会输出0.如果istore_1代表存储i,那么不管上边的什么顺序,最后不都是i加一并且被存储了吗.紧接着下边用一个iload_1来去i的值.但是为什么不出现预期的结果呢?


 镖师甲 回复于:2004-10-24 20:35:57

除非一种情况,JVM会因为某种原因来调整指令的执行顺序


 天下幽思 回复于:2004-10-25 12:57:03

最后不都是i加一并且被存储了吗.

问题是存在那里?


 bysea51 回复于:2004-10-25 14:14:32

在这里jvm里面有两个存储区,一个是暂存区(是一个堆栈,以下称为堆栈),另一个是变量区。
语句istore_1是将堆栈中的值弹出存入相应的变量区(赋值);语句iload_1是将变量区中的值暂存如堆栈中。
因为i = i++;是先将i的值(0)存入堆栈,然后对变量区中的i自加1,这时i的值的确是1,但是随后的istore_1又将堆栈的值(0)弹出赋给变量区的i,所以最后i = 0。
又因为i = ++i;是先对变量区中的i自加1,然后再将变量区中i的值(1)存入堆栈,虽然最后执行了istore_1,但也只是将堆栈中的值(1)弹出赋给变量区的i,所以i = ++i;的结果是i = 1。


 白色乌鸦 回复于:2004-10-25 16:21:00

楼上说得好清楚,
不知道从哪里可以看到这样的知识?


 镖师甲 回复于:2004-10-25 20:37:42

引用:原帖由 "bysea51" 发表:
在这里jvm里面有两个存储区,一个是暂存区(是一个堆栈,以下称为堆栈),另一个是变量区。
语句istore_1是将堆栈中的值弹出存入相应的变量区(赋值);语句iload_1是将变量区中的值暂存如堆栈中。
因为i = i++;是..........


描述的挺有道理,但不明白,为什么要直接对变量区的进行++而不对临时的堆栈先加然后在存储到变量区呢?


 镖师甲 回复于:2004-10-25 20:45:17

bysea51说的应该是正确的,单执行情况i++的时候只有一个iinc 1,1.
应该是改变bysea51所说的变量区的东西.顺便问一问bysea51,iinc 1,1.
指令在JVM规范里应该有的吧,我没有看过,有空看看.哈哈.


 镖师甲 回复于:2004-10-25 20:47:59

果然是JVM的Instruction


 sakulagi 回复于:2004-10-25 21:21:12

引用:原帖由 "白色乌鸦" 发表:
楼上说得好清楚,
不知道从哪里可以看到这样的知识?

Java VM Specification


 sakulagi 回复于:2004-10-25 21:25:57

引用:原帖由 "镖师甲" 发表:

描述的挺有道理,但不明白,为什么要直接对变量区的进行++而不对临时的堆栈先加然后在存储到变量区呢?

这个要看表达式的值的定义了。因为按照JVM Spec,任何一个算术操作都是把最终的表达式的计算结果放到Operand Stack里。
所以在定义了“i++这个操作的表达式的值为i,而不是i+1”之后,i++的计算过程中,Operand Stack实际上并不用变化。所以无论是从Operand Stack里进行inc还是直接对变量区进行inc,结果都是一样的:Operand Stack没变,变量区加一。


 qianwj 回复于:2004-10-26 12:38:12

i=++i


 blackcode 回复于:2004-11-01 14:38:12

:em11: 
#include <iostream>;
using std :: cout ;
using std :: endl ;
main()
{
  int i = 0; 
  i = i ++; 
  cout << "i = " << i << endl ; 
  
}
但在C++里上面输出的确是1呀,跟教科书上说的一样呀。


 xkhwj 回复于:2004-11-02 15:20:42

深刻呀。好好研究java


 tinywind 回复于:2004-11-02 15:30:51

i=i++在c中属于未定义的情况,可以用两种方式处理:
1)i++;i=i
2)temp=i;i++;i=temp
但在java中是明确规定使用后一种方式


 hills 回复于:2004-11-02 16:22:26

`   
 
    楼上几位说得都正确的。

    因为先赋值后为0了,因此后面的++将被忽略。

    这就像公式一样,记住就好了。

    学习一门计算机语言,很多规则是要死记而活用的!

     :em11: 


 jamesbang2003 回复于:2005-03-02 14:55:10

请问一下,javap是如何使用的,谢谢


 paladin00 回复于:2009-06-30 10:43:06

java的编译器在遇到i++和i- -的时候会重新为变量运算分配一块内存空间,以存放原始的值,而在完成了赋值运算之后,将这块内存释放掉.

(转)[url=http://java.chinaitlab.com/base/21363.html]http://java.chinaitlab.com/base/21363.html


 aaaaa5aa 回复于:2009-07-01 12:22:31

这种问题不要讨论,没什么大意义


 aaaaa5aa 回复于:2009-07-01 12:27:44

这种问题不要讨论,没什么大意义


 freelogin 回复于:2009-07-02 14:53:05

那意思是i使用过后+1
int i=0;
i=++i;
System.out.println(i);
i=1


 chance_xym 回复于:2009-07-02 22:44:30

从来不用i=i++,只用i=i+1




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=429688
转载请注明作者名及原文出处
分享到:
评论

相关推荐

    c语言数据结构字符串模式匹配算法.zip

    即从 j=0 起比较 S[i+j] 与 T[j],若相等,则在主串 S 中存在以 i 为起始位置匹配成功的可能性,继续往后比较( j逐步增1 ),直至与T串中最后一个字符相等为止,否则改从S串的下一个字符起重新开始进行下一轮的"匹配...

    数字图像锐化

    图像锐化(2010-08-03 16:10:31)转载▼标签: 杂谈 分类: Matlab MATLAB全称是MatrixLaboratory(矩阵实验室),一开始它是一种专门用于矩阵数值计算的软件,从这一点上也可以看出,它在矩阵运算上有自己独特的特点。...

    i.MX6-Android用户手册V2.4-2015.12.04.pdf

    4. 知识产权声明:文档强调了i.MX6-Android软件手册的版权所有者是保定市飞凌嵌入式技术有限公司,并指出未授权复制、传播或转载手册的部分将由违者自负后果。这反映了制造商对于其知识产权的保护意识和要求。 5. ...

    [转载]nlogn的最长子序列算法.rar_最长 排序_最长子序列

    这个主题由标题“[转载]nlogn的最长子序列算法.rar_最长 排序_最长子序列”所涵盖,我们将深入讨论这个问题,并结合描述中提到的网络摘录资料,提供详尽的解释。 首先,我们要明确“最长子序列”的概念。在给定的一...

    【转载】oracle笔试2.doc

    选项A和B错误是因为它们尝试使用"(" + ")"符号来表示外连接,这是Oracle8i之前的语法,而题目中明确提到Oracle9i支持ANSI/ISO标准的外连接语法,所以这种旧的语法不适用。C和E也是错误的,因为JOIN关键字不能与"(" +...

    转载muduo简单库文件

    【描述】:链接指向的博客文章讨论了muduo库中的“asynclogging”异步日志模块,这是一个高效且线程安全的日志记录功能,能够实现在多线程环境下的日志输出。在“asynclogging”中,日志不是立即写入磁盘,而是先...

    【转载】GitHub上关于微信跳一跳的模拟软件

    然而,有些技术爱好者利用编程技术,开发出了模拟软件,使得游戏可以自动化进行,这就是我们今天要讨论的“【转载】GitHub上关于微信跳一跳的模拟软件”。 该模拟软件是基于Python语言编写的,Python以其简洁明了的...

    转载软件测试试题

    1. **性能监控工具**:使用系统自带的性能监视器或者第三方工具(如Process Monitor、Task Manager等)收集CPU、内存、磁盘I/O等方面的使用情况。 2. **代码审查**:分析源代码查找可能存在的性能瓶颈。 3. **硬件...

    [转载]FPGA中差分信号的定义和使用(一) fpga开发.pdf

    在FPGA中,差分信号的输出需要在Pin Planner中定义I/O Standard为Bus LVDS类型的信号。同时,差分信号对必须按照芯片的定义来配置。在这里,我们使用ALTERA公司的CYCLONEIII系列的FPGA芯片,定义一个名字为DIF_OUT的...

    AT91RM9200_PIO.rar_9200_AT91rm9200 PIO_at91rm9200_pio

    此文件可能来源于一个技术分享网站,可能包含更多关于AT91RM9200或PIO的讨论、问题解答和其他相关资源。 总结来说,AT91RM9200的PIO是一个强大的硬件接口,通过灵活的配置和编程,可以适应多种嵌入式应用的需求。...

    UNIX高级编程

    5. **I/O模型**:讨论阻塞I/O、非阻塞I/O、多路复用(如select、poll、epoll)和异步I/O,帮助开发者设计高效的I/O处理程序。 6. **标准I/O库**:介绍stdio.h头文件中的函数,如printf、scanf系列,以及文件位置...

    二十三种设计模式【PDF版】

    o m m u n i c a t i n go b j e c t)的重复模式。这些模式解决特定的设计问题,使面向对象设计更灵活、优雅,最终复用性更 好。它们帮助设计者将新的设计建立在以往工作的基础上,复用以往成功的设计方案。 一个...

    2018青鸟学社纳新笔试题.docx

    【描述】: 原创作者田超凡,转载请获得许可 【标签】: 北大青鸟 【部分内容】 本试题是2018年北大青鸟学社纳新的笔试题目,主要测试应试者的基础Java编程知识。以下是部分题目及其涉及的知识点: 1. 题目描述了...

    Java字节码(.class文件)格式详解((转载)

    在提供的文件中,`Java字节码(一).docx`和`Java字节码(二).docx`可能详细介绍了字节码的不同方面,而`Java字节码(三).docx`可能进一步深入讨论了高级主题。`jbe-0.1.1`可能是JBE工具的一个早期版本,用于查看和编辑...

    2014年计算机视觉会议集

    2014年的计算机视觉会议集,汇集了当时该领域的最新研究成果和前沿技术,通过对视觉计算新方法的讨论,推动了相关技术的发展和应用。 会议集中的文章和论文通常涵盖了多个子领域,例如图像识别、图像处理、视频分析...

    C++技术

    这份文档可能涵盖了C++运行时库(C++ Runtime Library)的内容,它是一组由编译器提供的函数和对象,用于支持C++程序的基本操作,如内存管理、I/O流、异常处理等。了解C++运行库对于编写高效的代码和理解程序的内存...

    mina

    5. **NIO_TEST**:这可能是一些与Java NIO(非阻塞I/O)相关的测试代码或实验,MINA是基于Java NIO构建的,因此理解NIO对于使用MINA至关重要。 6. **MINA使用手记[1] _files**:这可能是一个文件夹,包含与第一篇...

    智能手机开启信息时代

    本文将围绕智能手机的作用及其对现代社会的影响展开讨论,并结合高效IT网提供的资源进一步探讨智能手机相关的技术知识。 #### 一、智能手机与信息时代的关联 在信息时代,智能手机成为了最重要的信息接收和传播...

    fintech_talk:金融科技相关研讨会讲座

    所有内容已获各位讲师原创授权,未经许可,禁止商业相关使用。转载请保留内容完整,并注明出处。 在线阅读: 或 。 pdf 版本 epub 版本 欢迎大家加入金融科技讨论群: QQ 群 I:335626996(已满) QQ 群 II:...

Global site tag (gtag.js) - Google Analytics