黑马程序员技术交流社区

标题: 开业第一问:求解这段程序的输出结果 [打印本页]

作者: 陈圳    时间: 2013-3-1 14:15
标题: 开业第一问:求解这段程序的输出结果
本帖最后由 陈圳 于 2013-3-2 11:03 编辑

package Day19;
class Test2
{
        public static void main(String[]args)
        {
                Test2 intdemo=new Test2();
                int i=0;
                intdemo.fermin(i);
                i=i++;
                System.out.println(i);               
        }
        void fermin(int i){
        i++;
        }
}
//打印结果:0实在想不通为什么...
作者: 偏執旳、靑春    时间: 2013-3-1 14:22
intdemo.fermin(i);???这是个神马函数啊???
作者: 张豪杰    时间: 2013-3-1 14:26
你fermin函数里的i++,实际上是fermin里的局部变量i 的自加运算,它的存在会随着fermin函数的结束而消失,跟全局变量i没半点关系。
class Test2
{
        public static void main(String[]args)
        {
                Test2 intdemo=new Test2();
                int i=0;
                intdemo.fermin(i);
                i=i++;//虽然上面调用了fermin,但是丝毫不影响这个i的结果,所以这里i再执行++之前,他的值还是0;
                System.out.println(i);               
        }
        void fermin(int i){
        i++;//这里自增的是fermin里面产生的副本值!!!不影响主函数中i的结果
        }
}
代码可以改成这样
class Test2
{
        public static void main(String[]args)
        {
                Test2 intdemo=new Test2();
                int i=0;
                i=intdemo.fermin(i);//把fermin函数里计算出的副本值(即临时变量),传递给全局变量i,这样就可以了
                i=i++;
                System.out.println(i);               
        }
        int fermin(int i){
        i++;
       return i;
        }
}
作者: 陈圳    时间: 2013-3-1 14:45
偏執旳、靑春 发表于 2013-3-1 14:22
intdemo.fermin(i);???这是个神马函数啊???

你都木有看清楚啊...
作者: 贾文泽    时间: 2013-3-1 14:57

  1. package Day19;
  2. class Test2
  3. {
  4.         public static void main(String[]args)
  5.         {
  6.                 Test2 intdemo=new Test2();
  7.                 int i=0;
  8.                 intdemo.fermin(i);     // i 是局部变量,下面那个方法中的 i 跟这个没有关系
  9.                 i=i++;                //赋值运算先算右边,【赋给 i 的是 i++; 这个表达式的值】,这个表达式的值是0,所以 i =0  
  10.                 System.out.println(i);               
  11.         }
  12.         void fermin(int i){
  13.         i++;
  14.         }
  15. }
复制代码

作者: 徐升2013    时间: 2013-3-2 00:51
陈圳 发表于 2013-3-1 14:45
你都木有看清楚啊...

我也是新手,对你这个问题挺感兴趣的 不过不理解原理我加入了局部变量y和z,在给y和z赋值的时候调用到I的时候i的自加动作才会保存下来,原理我也搞不太清楚,下面是图你看看,搞懂了之后别忘了通知我下 ,谢了

1.jpg (48.75 KB, 下载次数: 7)

1.jpg

作者: 徐升2013    时间: 2013-3-2 00:57
上面的图可以肯定一件事就是局部变量i=i++的时候 是先赋值,后自加。  从Z的输出就能看出来了
作者: 徐升2013    时间: 2013-3-2 01:53
哥们,你这个问题你别在研究了 记住别这么写就是了,这个问题涉及到栈内存执行操作的过程,总的来说你这么写永远都是0.java在内存中是做了自加的动作的但是又将0给覆盖了自加后的值,然后I又引用了这个0,所以结果是0,很绕吧,但是这个肯定是正确答案的,这个是查阅了很久最后看到的,一个人用反编译的方式把内存的运行方法给解释了之后得出的结果。已经研究3个小时了 汗死 睡觉去。
作者: 余勇    时间: 2013-3-2 02:03
我觉得这个问题不必深入,会用就行,又不是开发java,而是java开发
作者: 陈圳    时间: 2013-3-2 08:29
起航 发表于 2013-3-2 01:53
哥们,你这个问题你别在研究了 记住别这么写就是了,这个问题涉及到栈内存执行操作的过程,总的来说你这么 ...

知道了...谢谢了大家了
作者: 克零岚    时间: 2013-3-2 10:04
这是楼主的代码:
package Day19;
class Test2
{
         public static void main(String[]args)
         {
                 Test2 intdemo=new Test2();
                 int i=0;
                 intdemo.fermin(i);
                 i=i++;                                    //首先明确i++是什么含义,i++表示先调用再+1,所以i++实际赋值给i的是0,故而输出后是0;修改为++i会得到你想要的结果
                 System.out.println(i);               
        }
         void fermin(int i){
         i++;                                  //fermin(int i)这个函数觉得毫无意义,大概你是想通过这个函数对 i 进行操作,但定义的 i  是局部变量,只在对应方法内部起作用,也就是说fermin
         }                                            //函数对  i   的修改并不能反应到main方法中 i  的改变
}

本人修改后的代码,希望是你想得到的输出(如下)
  1. package Day19;
  2. class Test2
  3. {
  4.          public static void main(String[]args)
  5.          {
  6.                  Test2 intdemo=new Test2();
  7.                  int i=0;
  8.                 int i2= intdemo.fermin(i);
  9.                  i=++i2;                                
  10.                  System.out.println("输出结果为:"+"\t"+i);  
  11.         }
  12.          int  fermin(int i){   
  13.          return ++i;                              
  14.          }                                          
  15. }
复制代码
运行修改后的程序:
  1. 输出结果为:        2
复制代码

作者: 克零岚    时间: 2013-3-2 13:08
重新在网上查了查,原来与符号的优先级有关系。
  1. 对比两段程序和它们的汇编代码(javap -c xxx得到):
  2. int i=0;     i=i++;                                                 int i=0;         i=++i;
  3.      ------------------------------------------------------------------------------------  
  4.      0: iconst_0                                                       0: iconst_0
  5.     1: istore_2                                                         1: istore_2
  6.     2: iload_2                                                           2: iinc 2, 1
  7.     3: iinc 2, 1                                                           3: iload_2
  8.     4: istore_2                                                          4: istore_2
  9.     5: return                                                              5: return
复制代码
它们区别在于2,3两句。
    从优先级来看  "前++" >" =" > "后++",所以汇编代码清楚地显示了代码执行地过程。
    第二段代码地结果是1,没有问题。
    从汇编代码来看,=赋值地过程是先利用临时变量计算=右边地值,然后在赋给左边地变量。
    这样,我们就很容易解释第一段代码地运行结果了:
    临时变量先得到i原来地值是0(汇编代码1),这时候考虑优先级,=大于后++,所以临时变量就执行赋值操作,之后临时变量先读出i地值(汇编代码2),再进行++操作(汇编代码3),但是++操作只是在临时变量自己身上加一,不会影响原来地i值。
    按照上面地思路再分析第二段代码,也就顺理成章了:)
                相信到这里你已经明白了!
     





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2