说说这题我的理解吧!第一眼看的时候,我也懵了,然后自己研究了一个小时,谈不上,也是上网找资料,还没整理好,拿出来说说吧!勿喷
1、先看C#中的执行,C#公共运行环境CLR与Java的JVM差不多,确实如此:
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int j = 0; for(int i=0;i<10;i++) { j=j++; } System.Console.WriteLine("j = " + j); } } } 运行结果也是0; 2、C语言运行:(看图片吧!)论坛为什么图片不能插入到具体的位置,纠结,大家就看图片吧! 3、Java运行(看图片) 4、调试Java时的现象(看图片) 为什么结果出人意料,我们看下C#帮助文档MSDN(ps:其实它有个论坛,现在CSDN八成就是模仿他) MSDM中的一句言简意赅话: 第一种形式是前缀增量操作。该操作的结果是操作数加 1 之后的值。 第二种形式是后缀增量操作。该运算的结果是操作数增加之前的值。 那么我们理解这题,就可以这样说,j = j++;执行的本质,是将j自加前的值赋值给j,所以一直0;ps:执行顺序是++运算符优先于=赋值运算符,貌似可以解释通。 找了半天,看到有人找到JVM的解释: jvm里面有两个存储区,一个是暂存区(是一个堆栈,以下称为堆栈),另一个是变量区。
语句istore_1是将堆栈中的值弹出存入相应的变量区(赋值);语句iload_1是将变量区中的值暂存如堆栈中。
因为i = i++;是先将i的值(1)存入堆栈,然后对变量区中的i自加1,这时i的值的确是2,但是随后的istore_1又将堆栈的值(1)弹出赋给变量区的i,所以最后i =1。 注意:istore_1、iload_1是反编译的语言,看不懂!你要是懂汇编和反汇编应该知道吧!反正我不懂。 我理解的:(我觉得能解释通) java的编译器在遇到i++和i--的时候会重新为变量运算分配一块内存空间,以存放原始的值,而在完成了赋值运算之后,将这块内存释放掉。先将i的原始值存放在变量区,然后i++,此时栈中的i确实为1,执行赋值的时候,是把变量区中的值(原始值)赋值到栈中,所以又为0 c/c++中没有另外设置一个临时变量或是临时空间来保存i,所有操作都是在一个内存空间中完成的。所以会出现结果为10 下面附一张解释图(别人的)。不知道大家看懂没有,不懂就多看看,或找资料,因为我看一个小时,才得出我的理解,如上红字
|