Java增量运算符查询(++ i和i ++)

时间:2014-06-26 04:16:57

标签: java increment

我有以下代码:

public class Book {
    private static int sample1(int i) {
        return i++;
    }
    private static int sample2(int j) {
        return ++j;
    }

    public static void main(String[] arguments){ 
        int i = 0;
        int j = 0;
        System.out.println(sample1(i++)); //0
        System.out.println(sample1(++i)); //1
        System.out.println(sample2(j++));//1
        System.out.println(sample2(++j));//2
        System.out.println(i);//2
        System.out.println(j);//2
    }
}

我的预期输出在评论中。实际输出如下:

0
2
1
3
2
2

我对函数调用和incemental运算符感到困惑。有人可以解释实际结果吗?

7 个答案:

答案 0 :(得分:15)

由于sample1sample2只是修改自己的局部变量ij(不是调用方法的变量),所以如果我们更清楚在没有这些修改的情况下重写它们:

private static int sample1(int i) {
    return i;   // was 'i++', which evaluates to the old i
}
private static int sample2(int j) {
    return j + 1;   // was '++j', which evaluates to j after incrementing
}

在这一点上直接替换它们是直截了当的 - sample1(...)变为...,而sample2(...)变为... + 1

int i = 0;
int j = 0;
System.out.println(i++);
System.out.println(++i);
System.out.println((j++) + 1);
System.out.println((++j) + 1);
System.out.println(i);
System.out.println(j);

我们可以通过将增量分成它们自己的命令来使这一点更加清晰。 i++评估i的原始值,因此在运行周围命令后递增i ;相比之下,++i就像在运行周围命令之前递增i 。所以我们得到:

int i = 0;
int j = 0;
System.out.println(i);
i++;
++i;
System.out.println(i);
System.out.println(j + 1);
j++;
++j;
System.out.println(j + 1);
System.out.println(i);
System.out.println(j);

。 。 。在这一点上,应该直截了当地查看它将会输出什么。

这一切都有意义吗?

答案 1 :(得分:11)

首先,您需要了解x++++X;

之间的区别

如果是x++

首先使用当前值,然后将增加当前值。 这意味着您将获得操作的x的当前值以及您是否 下次使用x将获得递增的值;

如果是++x

首先,当前值将递增,然后将使用它(递增值),这意味着您将获得递增的值 在此操作和此操作后的其他操作。

现在让我们分开代码并单独讨论

方法:sample1():

private static int sample1(int i) {
    return i++;
}

此方法将采用int并首先返回它然后尝试递增但是在返回后变量i将超出范围,因此它将永远不会 完全递增。 exp in: 10-> out 10

方法:sample2():

private static int sample2(int j) {
    return ++j;
}

此方法将获取一个int并首先递增它然后返回它。 exp in: 10-> out 11

在这两种情况下,只有变量会在本地更改,这意味着如果从main方法调用,main方法的变量将不受更改的影响 (因为sample1()和sample2()正在复制变量)

现在为主要方法的代码

System.out.println(sample1(i++)); // it's giving sample1() `i=0` then making `i=1` 
                                  //  so  sample1() will return 0 too;

System.out.println(sample1(++i)); // it's making `i=2` and then giving sample1() `i=2`
                                  // so sample1() will return 2;

System.out.println(sample2(j++)); // it's giving sample2() `j=0` then making `j=1` 
                                  // so sample2() will return 1;

System.out.println(sample2(++j)); // it's making `j=2` giving sample2() `j=2` then  
                                  // so sample2() will return 3;

答案 2 :(得分:8)

您正在体验前缀和后缀运算符的乐趣。

前缀运算符++i将变量i增加一个,然后在表达式中使用它,其中后缀运算符(i++)使用{{在递增之前的表达式中的1}}。

这意味着你的方法i没有做任何事情;它会计算包含sample1的表达式,但由于该表达式是一个return语句,因此局部变量i超出范围,我们不能再修改它了。

相比之下,

i会在返回之前递增sample2的本地副本,这就是您打印的j值高于预期的原因。

答案 3 :(得分:2)

易于:
1)第一次通话:
a)向sample1()提供i(== 0),返回0(然后递增参数i,然后丢弃)。
b)因i ++而增加i。 我现在是1 c)打印功能结果:0。

2)第二次通话:
a)因为++ i而增加i。 我现在2 b)向sample1()提供i(== 2),返回2(然后递增参数i,然后丢弃)
c)打印功能结果:2。

3)第三次电话:
a)向sample2()提供j(== 0),使参数递增,因此返回1.
b)因为j ++而增加j。 j现在为1 c)打印功能结果:1。

4)第四次电话:
a)因为++ j而增加j。 j现在为2 b)将j(== 2)提供给sample2(),使参数递增,因此返回3.
c)打印功能结果:3。

5& 6)第五和第六电话:
a)打印j的值:2。

这里要记住的关键是i ++在将变量作为参数传递之后递增变量,而++ i在将变量作为参数传递之前递增变量。

希望这有帮助

答案 4 :(得分:2)

第一次印刷

呼叫前

:i = 0

通话后递增

调用sample1,值为0

样本1返回0,丢弃增量

电话后

:i = 1

第二次印刷

呼叫前

:i = 1

呼叫前递增

调用sample1,值为2

sample1返回2,丢弃增量

电话后

:i = 2

第3次印刷

呼叫前

:j = 0

通话后递增

调用sample2,值为0

sample2增量0到1,返回

打印

1

将j增加到1

电话后

:j = 1

第4次印刷

呼叫前

:j = 1

呼叫前递增

将j增加到2

调用sample2,值为2

sample2增量2到3,返回

打印

3

电话后

:j = 2

第5次印刷

打印我

打印

2

第6次印刷

打印j

打印

2

答案 5 :(得分:2)

它们都将变量i增加一个,如i = i + 1;

区别在于

++ i首先递增值然后返回

i ++首先返回值,然后递增

这种行为差异在for循环中无关紧要。

如果你想知道差异,试试这个:

int x = 0;
int y = x++;

int x = 0;
int y = ++x;

此处x++返回值然后递增它,但++x首先递增该值然后返回该值

答案 6 :(得分:2)

形成你的榜样,

  private static int sample1(int i) {
    return i++;
  }
  private static int sample2(int j) {
  return ++j;
  }

  public static void main(String[] arguments)
  { 
  int i = 0;
  int j = 0;
  System.out.println(sample1(i++)); //0
  System.out.println(sample1(++i)); //1
  System.out.println(sample2(j++));//1
  System.out.println(sample2(++j));//2
  System.out.println(j);//2
  System.out.println(j);//2
  }
  1. i = 0; sample1(i ++) - >它在sample1中传递'0' - >返回i ++ so,0(++) 这里它返回0但增加到1,所以println = 0但最后我需要1
  2. i = 1; sample1(++ i) - >它传递'2' - >在sample1中返回i ++ so,2(++) 这里它返回2,所以println = 2
  3. j = 0; sample2(j ++) - >它传递'0' - >在sample2中返回++ j so,(++)0 这里它返回1,因此println = 1。
  4. j = 1; sample2(++ j) - >它通过++ 1 => 2,在sample2中返回++ j so,(++)2 这里它返回3,所以println = 3.但是增量在sample2中结束,而不是在 主要因此j仍然持有2。
  5. j = 2
  6. j = 2