c=0,for循环 为啥c还是等于0

脾话钱 发布于 08/24 13:46
阅读 192
收藏 0
public class Test03 {
    @Test
    public void test01(){
        int c=0;
        int d=0;
        for (int i = 0; i < 10; i++) {
            c=c++;
        }
        System.out.println(c);
        for (int i = 0; i < 10; i++) {
            c=c++;
            d=c++;
        }
        System.out.println(c);
        System.out.println(d);
    }
}
加载中
1
tcxu
tcxu

将以下源码产生的字节码文档进行反编译:

public class Test{
    public static void main(String[] args){
        int c=0;
        for(int i=0;i<10;i++)
        c=c++;
        System.out.println(c);
    }
}

Dos 窗口的 指令:
javac Test.java
javap -c Test

Dos 窗口的输出及我添加的注释:

...

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0                           //把0放到栈顶
       1: istore_1                           //把栈顶的值放到局部变量 1 中,即c中
       2: iconst_0                            //把0放到栈顶
       3: istore_2                            //把栈顶的值放到局部变量 2 中,即 i 中
       4: iload_2                            //把 i 的值放到栈顶,首次,栈顶的值是 0
       5: bipush        10                //将常量 10 压入栈中
       7: if_icmpge     21    // 将操作数栈中的两个int值弹出栈,然后比较它们,如果value2(即这里 i 的 值)大于或等于value1(即这里的 10),则跳转至 21 行执行,否则就继续执行
      10: iload_1                    //把 c 的值放到栈顶,也就是说此时栈顶的值是 c 的值 (0) 
      11: iinc          1, 1         //给局部变量表的 1 号位置, 即 c 的 位置 的 int 值增加  1
      14: istore_1                //把栈顶的值(0), 放到局部变量 1,即 c 中,c 的值又变成了 0 

      15: iinc          2, 1         //给局部变量表的 2 号位置, 即 i 的 位置 的 int 值增加 1
      18: goto          4            //跳到第4行,继续执行
      21: getstatic     #2      // Fieldjava/lang/System.out:Ljava/io/PrintStream; 即,下载 字段:System.out 
      24: iload_1                      //把 1 号位置,即 c 的值放到栈顶
      25: invokevirtual #3      // Method java/io/PrintStream.printl:(I)V 调用 方法 printl(...),输出 c 的值
      28: return                     //返回

回答提问:"c=0,for循环 为啥c还是等于0?"
请看 for 循环体内 对变量 c 的操作。


步骤1 (第10行) : 把 c 值(其值是 0)拷贝到临时变量区("操作数栈")。 


步骤2 (第11行) : c 值加 1,这时候 "局部变量表"的 1 号位置,即 c 的值 变成了 1。 


步骤3 (第14行) :  返回临时变量区的值,即 "操作数栈" 顶的值(注意这个值是 0,没修改过), 放到"局部变量表"的 1 号位置,即 c 的位置,使得  局部变量表 c 的值又成了 0。
    由此可见,无论循环多少次, 每次循环结束时,c 的值总是 0。


参考:
java 中的 i=i++

JVM指令集介绍


 

0
TD2575
TD2575
++的用法是先进行赋值后进行自加。所以循环为0
0
D
Drayx

++如果在后面,是先把值拿来用,再+1,不难理解

0
前端大师傅
前端大师傅

一楼说得是对的,楼主的问题在于不太了解 x++和++x的区别。

在下来分解一下这个循环楼主就明白了。

for (int i = 0; i < 10; i++) {
            c=c++;
        }

for操作虽然很普遍,但其实操作是整合了四个步骤,很多初学者不了解这个机制,在下来分解楼主就明白了:

第一步 int i=0;

第二步 执行i<10; 如果为true,则执行第三步。如果为False则退出

第三步 执行 {}里面的内容。即c=c++;

第四步 执行 i++;无条件跳转到第二步(注意这里是无条件)

按楼主的代码在计算机中是这样执行的:

1. int i=0;

第一次

2. i<10 (i为0,0<10所以是true)

3.c=c++;//关键点分成三步,相信楼上都不明白这个原因:

1)c++ c先赋值出去,但这时并没有=操作。=操作符优先级别最后。

2)c++ 自增 这时c的值为1。

3)通过=操作符将原先的0赋值给c这时c又变回了0.

4.i++//为1进入2

第二次

2. i<10 (i为1,1<10所以是true)

3.c=c++;//这是c初值仍然是0,然后再进行c=c++之后仍然是零。

4.i++//为1进入2

...由于相同中间3-10省略直接第11次...

2.i<10 (i=10,i==10不满足直接退出)3-4不执行。

由于c一直都是零,所以最终打印出来还是零

另一楼说得并不算完全准确,楼主的问题并不是c++ 而是c=c++!

其实如果楼主直接c++再打印是对的,而楼主偏偏多此一举的赋了值就完全错了。

c++加了一个左值去存储变成c=c++;是最大的问题

返回顶部
顶部