无法理解java算法中的执行顺序(k =和++ k)

时间:2016-11-28 10:40:01

标签: java algorithm

我最近不得不做一个Java考试,并且想知道我遇到的一个问题。问题如下:

在没有任何参数的情况下运行以下代码会打印什么...

public class TestClass {

    public static int m1(int i){
        return ++i;
    }

    public static void main(String[] args) {
        int k = m1(args.length);
        k += 3 + ++k;
        System.out.println(k);
    }

}

答案是1到10之间的数字。 我原来的答案是7,而他们说正确答案是6。

我的逻辑:

m1 sets k to 1, as it's ++i and thus gets incremented prior to returning.
then the += is unrolled, making: 'k = k + 3 + ++k'.
++k is executed, making k 2.
Replace the variables with their value: 'k = 2 + 3 + 2'
k = 7.

然而,他们将其称为k = 1 + 3 + 2。 在执行++ k之前,有没有人可以解释为什么首先替换变量?

4 个答案:

答案 0 :(得分:3)

postpre增量运算符对临时值进行操作,该临时值在等式之后被赋值。这意味着

i = 0;
i = i++ // still 0
i = ++i // 1

因为右侧是临时的,并且在作业之前没有反映左侧。

根据你的逻辑,这将导致

int i = 0;
i = ++i // 2 - wrong.

答案 1 :(得分:2)

没有任何参数意味着args.length = 0

int k = m1(args.length); m1(0)= ++ 0 = 1

所以k = 1

k + = 3 + ++ k;

k = k + 3 = 4。 ++ k = ++ 1 = 2

所以

4 + 2 = 6

答案 2 :(得分:2)

我确实相信即使顺序正确,JVM也会使用k值准备语句,所以这看起来像这样(简化):

  k += 3+ ++k; // k = 1
> k = k + 3 + ++k // k = 1
> k = 1 + 3 + ++k // k = 1 
> k = 1 + 3 + 2   // k = 2

进一步说明:

  int k = 2;
  k *= 3 + ++k; // > 12
> k = 2 * 3 + ++k // k = 2
> k = 2 * 3 + ++k // k = 2
> k = 2 * 3 + 3   // k = 3
> k = 2 * 6 = 12

我们看到*=最后是以起始值完成的。

  int k = 1;
  k += 3 + ++k + ++k; // > 9
> k = k + 3 + ++k + ++k // k = 1
> k = 1 + 3 + ++k + ++k // k = 1
> k = 1 + 3 + 2   + ++k // k = 2
> k = 1 + 3 + 2   + 3   // k = 3
> k = 9

所以我们可以看到,对于后期增量,这不是真的。这些将在第一次读取时获得k的值

我看到的唯一逻辑是从左到右计算值,但操作符仅根据顺序执行。在第一次阅读期间评估的后期和预增量除外

答案 3 :(得分:1)

好的,说明++运算符优先于+ =运算符是正确的,因此在执行++运算之前不会展开+ =但是在执行任何操作之前解释器首先评估大多数操作符的操作数,这是从左到右完成的。

所以在你的例子中,k = 1,

k += 3 + ++k;

实际上是:

1 += 3 + ++k;

然后评估++ k,因为它具有优先权并变为:

1 += 3 + 2;

+具有优先权并变为:

1 += 5;

此时+ =展开,当然这给出了6 ... QED

修改

虽然运算符优先级很重要但Java确实从左到右评估,除非优先级另有规定:

例如:

a + b + c * d

虽然c * d具有优先权,但不会先评估它。

a + b + c * d
  ^   ^
 these 2 operators compared

两者都具有相同的优先级,因此从左到右进行评估,首先评估a + b(让我们调用结果d)。

 d + c * d
   ^   ^
 next these 2 operators compared

*优先于+,因此首先评估c * d