A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 彭旭文 中级黑马   /  2012-9-22 23:14  /  2776 人查看  /  13 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

       刚在论坛上看到一张关于“i++”问题的帖子,关于i=i++内存空间分配问题,思后不得其解,在此提出,希望得到大家的帮忙!...原帖内容如下:
public class Test {
        public static void main(String[] args) {
                int i = 10;
                int j = 20;
                i = i++;
                System.out.println(i);
        }
}
打印结果:i=10。
按照自己的想法,i=i++语句之后,i就会进行自增,然后再执行System.out.println(i)语句。打印结果应该为11。
我想了解一下,从Main函数开始,每条语句是如何在内存中分配空间的,特别是i=i++这一条语句,希望得到大家的帮助...谢谢!

13 个回复

倒序浏览
i++ 就是整个函数体执行完毕后才自增一,++i 才是先自增在执行后边语句(打印),不信你试试!~~~~稍后上图
回复 使用道具 举报
杰~~~ 发表于 2012-9-22 23:32
i++ 就是整个函数体执行完毕后才自增一,++i 才是先自增在执行后边语句(打印),不信你试试!~~~~稍后上图 ...

你说的是整个main函数吗?那如何解释for(i=0;i<3;i++)这个语句中的i++,难道也是等for函数体结束了才自增?那么不就与for循环路径相违背了吗?继续请教一下...
回复 使用道具 举报
本帖最后由 邓利军 于 2012-9-23 11:19 编辑

当自增参与运算的时候,++在前在后是有区别的,
i= i++;//先进行临时存储,再自增,再将临时存储的值进行赋值给左边的i。
具体来说就是这样:
    因为右边这个i在前,++在后,说明右边这个i的数值需要参与++以外的运算。比如赋值给左边这个i的运算。
  所以,运算过程是这样的,有三步:
  右边运算: 1先将i变量中的数据,进行临时存储。
                     temp = i,这时这个temp值为10,明白吧?????
                 2,自增运算。      
                     i = i+ 1;
                     i = 11;
左边运算: 3,将临时存储i数据的变量赋值给左边的i
                    i = temp;
                    i = 10;

因此输出的就是这个临时存储的数据10,
相反,如此是 i=++i,那么就先自增,只走两步,第一,先自增,右边的i为11, 第二,后赋值,左边的i为11,那么输出结果就是11了.    如果还有问题,请回复.

______________________________

再次回复楼主:

在这个环境下,第二步确实没有起到什么作用.  
也符合i++的用法,只是这个环境中,没有使用到++而已.
我举个用到第二步的例子,这得扩展知识量了,可能问题会变得复杂.......咱们就当交流学习,,如下:
class  Test2
{
public static void main(String[] args)
{
int a = 3,b;
b = (a++)+(++a)*2+(a++)+(++a);  //b由4个值相加得来,分别是 3+5*2+5+7,结果是b=25..你先运行一下肯定是25.
System.out.println("b="+b);
}
}
第一个括号,先使用3,然后加自增为4给第二个括号,此时a为4  ,这一段使用值为3
第二个括号,先自增为4+1为5,使用5,然后乘以2为10,此时a为5,这一段使用值为10
第三个括号,先使用为5,然后自增为5+1为6,此时a为6             ,这一段使用值为5
第四个括号,先自增为7,使用a=7,此时a为7                            ,这一段使用值为7
结果加起来是b=25..

有问题请再回复.




回复 使用道具 举报
public class NetTest {
       
        public static void main(String[] args){
               
                int i=10;//定义i为类型为int(整数),值为10的变量
               
                int j=20;//定义j为类型为int(整数),值为20的变量
               
                i=i++;//整个主函数执行完+1
               
                System.out.println(i);//打印i
        }//执行i++

}
回复 使用道具 举报
Leo.Peng 发表于 2012-9-22 23:45
你说的是整个main函数吗?那如何解释for(i=0;i

对呀,第一次循环结束才会自增1 啊
回复 使用道具 举报
杰~~~ 初级黑马 2012-9-23 00:44:35
7#
邓利军 发表于 2012-9-23 00:13
当自增参与运算的时候,++在前在后是有区别的,
i= i++;//先进行临时存储,再自增,在将临时存储的值进行赋 ...

您这个都上二进制数了,有点乱!
回复 使用道具 举报
邓利军 发表于 2012-9-23 00:13
当自增参与运算的时候,++在前在后是有区别的,
i= i++;//先进行临时存储,再自增,在将临时存储的值进行赋 ...

谢谢你回答我的问题...如果按你这么说,JVM岂不是在栈内存中开辟两个变量空间(i、temp),先把i的值赋给temp(第一步),然后又把temp的值赋给i(第三步),到最后i的值还是10,那么第二步不就起不作用了吗?岂不是不符合i++用法?我想具体了解下这条语句在内存中的具体操作细节...继续请教...:)

点评

我的理解是错的,其实只开了一个空间,一个变量一个空间.真不好意思.  发表于 2012-9-23 22:26
多运算时,空间开辟更复杂,有老师说了,别太纠结这个.现在大家都知道结果就行.  发表于 2012-9-23 11:31
i=10;i=i++;可以这么理解,一开始就有一个空间,然后新开一个空间temp,老空间自增为11,新空间temp被赋值为10,使用这个10.此时仍有两个空间,两个值.  发表于 2012-9-23 11:29
回复 使用道具 举报
张金 中级黑马 2012-9-23 01:05:15
9#
本帖最后由 张金 于 2012-9-23 01:06 编辑

   是这样的,在i=i++这句里,完成了三次操作。
第一次,是i临时找个地方存储了起来,也就是先出去,找个地方临时存储。
第二次,就是自增,就是原来存储i的空间里的i完成自增变成11.
但是,到第三次,i临时存储的10又 回来赋值了一次,所以最后打印的结果应该为10.D:\

AIV)UQH8OHPE{6HIN$57LH9.jpg (18.19 KB, 下载次数: 31)

AIV)UQH8OHPE{6HIN$57LH9.jpg
回复 使用道具 举报
杰~~~ 发表于 2012-9-23 00:33
对呀,第一次循环结束才会自增1 啊

如果你在main主函数中写一个FOR循环:
for(i=0;i<3;;)
{
System.out.println(i);
i++
}
//按你的说法,应该在这个地方执行+1?我觉得如果在这里+1,语句应该继续往下读,不应该回去判断i<3,那么循环怎么继续循环呢?我想详细了解i=i++在内存中的具体操作细节...请问你能给我讲讲吗?谢谢...
回复 使用道具 举报
彭旭文 发表于 2012-9-23 00:49
谢谢你回答我的问题...如果按你这么说,JVM岂不是在栈内存中开辟两个变量空间(i、temp),先把i的值赋给 ...

没事,相互讨论,相互交流技术...呵呵!:)
回复 使用道具 举报
张金 发表于 2012-9-23 01:05
是这样的,在i=i++这句里,完成了三次操作。
第一次,是i临时找个地方存储了起来,也就是先出去,找个地 ...

谢谢你的回答,初步了解了一下!想再详细了解一下temp变量在内存中的变化...
回复 使用道具 举报
其实,学习的初期,不建议,什么都刨根问底的去学,没 有那么多的时间去把握,也因为知识面的局限,很难完全弄懂的。
就像这个问题,其实,理解到上面的程度就可以了。如果再细究,就涉及的底层的东西了。
就是,整个的编译过程,需要去了解,每一次操作时,存储数据的地址值,都需要细究。这个就很底层了。
没有编译原理,或者底层的知识,是不可能完全理解的。
所以,我觉得没必要那样一个一个的去扣,还是整体把握,把前面的视频看完,代码自己都能敲出来后,再去一个一个的细究。
这样,不会浪费时间的,毕竟,我们这是企业培训,希望大家尽快的能就业。
所以,尽量都能找到一个对自己而言,多快好省的学习方法,而不是纠结于一个又一个小细节。
我觉得,再学习java的过程中,完美主义绝对是性格的缺陷。有时需要一点陶渊明的不求甚解。
回复 使用道具 举报
杰~~~ 发表于 2012-9-22 23:32
i++ 就是整个函数体执行完毕后才自增一,++i 才是先自增在执行后边语句(打印),不信你试试!~~~~稍后上图 ...

此言差矣
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马