zoukankan      html  css  js  c++  java
  • 关于i++和++i

    初学Java,经常看到i++和++i的一些问题,在此整理一下。

    首先看下面一个小程序:

    public class atest{
    
        public static void main(String args[]){
           int s=1,m=1,n=1,p=1;
           s++;
           ++m;
           n=n++;
           p=++p;
           System.out.println("s="+s+"; m="+m+"; n="+n+"; p="+p);
       }
    }

    输出为s=2; m=2; n=1; p=2

    这里比较难以理解的应该是n的值,下面我们对程序进行反编译进行分析:


    E: est>javap -c atest
    Compiled from "atest.java"
    public class atest {
    public atest();
    Code:
    0: aload_0
    1: invokespecial #1 // Method java/lang/Object."<init>":
    ()V
    4: return

    public static void main(java.lang.String[]);
    Code:
    0: iconst_1
    1: istore_1
    2: iconst_1
    3: istore_2
    4: iconst_1
    5: istore_3
    6: iconst_1
    7: istore 4
    9: iinc 1, 1
    12: iinc 2, 1
    15: iload_3
    16: iinc 3, 1
    19: istore_3
    20: iinc 4, 1
    23: iload 4
    25: istore 4
    27: getstatic #2 // Field java/lang/System.out:Ljava/
    io/PrintStream;
    30: new #3 // class java/lang/StringBuilder
    33: dup
    34: invokespecial #4 // Method java/lang/StringBuilder."<
    init>":()V
    37: ldc #5 // String s=
    39: invokevirtual #6 // Method java/lang/StringBuilder.ap
    pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    42: iload_1
    43: invokevirtual #7 // Method java/lang/StringBuilder.ap
    pend:(I)Ljava/lang/StringBuilder;
    46: ldc #8 // String ; m=
    48: invokevirtual #6 // Method java/lang/StringBuilder.ap
    pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    51: iload_2
    52: invokevirtual #7 // Method java/lang/StringBuilder.ap
    pend:(I)Ljava/lang/StringBuilder;
    55: ldc #9 // String ; n=
    57: invokevirtual #6 // Method java/lang/StringBuilder.ap
    pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    60: iload_3
    61: invokevirtual #7 // Method java/lang/StringBuilder.ap
    pend:(I)Ljava/lang/StringBuilder;
    64: ldc #10 // String ; p=
    66: invokevirtual #6 // Method java/lang/StringBuilder.ap
    pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    69: iload 4
    71: invokevirtual #7 // Method java/lang/StringBuilder.ap
    pend:(I)Ljava/lang/StringBuilder;
    74: invokevirtual #11 // Method java/lang/StringBuilder.to
    String:()Ljava/lang/String;
    77: invokevirtual #12 // Method java/io/PrintStream.printl
    n:(Ljava/lang/String;)V
    80: return
    }

    对相关部分进行分析,注释如下:

    0: iconst_1                       //把1放到栈顶
    1: istore_1                       //把栈顶的值放到局部变量1中,即s
    2: iconst_1                       //把1放到栈顶
    3: istore_2                       //把栈顶的值放到局部变量2中,即m
    4: iconst_1                       //把1放到栈顶
    5: istore_3                       //把栈顶的值放到局部变量3中,即n
    6: iconst_1                       //把1放到栈顶
    7: istore 4                        //把栈顶的值放到局部变量4中,即p
    9: iinc 1, 1                       //把局部变量1(也就是s),增加1,这个指令不会导致栈的变化,s此时变成2
    12: iinc 2, 1                     //把局部变量2(也就是m),增加1,这个指令不会导致栈的变化,m此时变成2
    15: iload_3                      //把局部变量3(也就是n)的值放到栈顶,此时栈顶为1
    16: iinc 3, 1                     //把局部变量3(也就是n),增加1
    19: istore_3                     //把栈顶的值放到局部变量3(也就是n)中
    20: iinc 4, 1                     //把局部变量4(也就是p),增加1
    23: iload 4                       //把局部变量4(也就是p)的值放到栈顶,此时栈顶为2
    25: istore 4                      //把栈顶的值放到局部变量4(也就是p)中

    由此看见,i=i++是先将i的值放到栈顶,而后对i进行操作,最后返回给i的栈顶值还是先前的值,而i=++i是先对i进行操作,然后将i的值放到栈顶,最后返回给i的栈顶值也就是计算后的值。

    扩展练习:

    public class atest{
    
        public static void main(String args[]){
           int s=0,m=0,n=0,p=0;
           for(int i=0;i<100;i++){
               s++;
               ++m;
               n=n++;
               p=++p;
           }
           System.out.println("s="+s+"; m="+m+"; n="+n+"; p="+p);
       }
    }
  • 相关阅读:
    ubuntu12.04 安装eclipse
    loj 1429(可相交的最小路径覆盖)
    loj 1406(状态压缩)
    mysql数据库表插入单条数据/批量插入数据
    window7安装MongoDB详细步骤
    django中的setting全局变量的导入
    django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)
    DjangoDRF序列化组件使用
    python并发编程知识点总结
    协程+IO切换实现并发
  • 原文地址:https://www.cnblogs.com/alansheng/p/4422251.html
Copyright © 2011-2022 走看看