27

谁能解释一下不同的间距如何影响一元运算符?

int i = 1;
int j = i+ + +i; // this will print j=2
int k = i++ +i; // this will print k=3
int l = i+++i; // this will print l=3
int m = i++++i; // compile time error

.

4

2 回答 2

43

首先,让我们把它分成三个不能交互的不同情况:

int i = 1;
System.out.println(i+ + +i); // 2

int j = 1;
System.out.println(j++ +j); // 3

int k = 1;
System.out.println(k+++k); // 3

现在让我们用括号重写它们:

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

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

int k = 1;
System.out.println((k++) + k);

第一次操作

在这里,我们不能使用前缀或后缀 ++ 运算符,因为我们没有++任何地方的标记。相反,我们有一个二元 + 运算符和两个一元 + 运算符。

第二次操作

这个很简单:就像它读起来的那样,一个后缀 ++ 运算符,后跟一个二元 + 运算符(不是+j可能暗示的一元 + 运算符)。

第三次操作

最后一行被解析为(k++) + k而不是k + (++k). 在这种情况下,两者实际上都会给出相同的答案,但我们可以通过使用两个不同的变量来证明哪个是哪个:

int k1 = 1;
int k2 = 1;
System.out.println(k1+++k2); // Prints 2
System.out.println(k1); // Prints 2
System.out.println(k2); // Prints 1

如您所见,它k1是递增的,而不是k2.

k+++k被解析为k, ++, +,的标记的原因k是由于JLS 的第 3.2 节,其中包括:

每一步都使用尽可能长的翻译,即使结果最终不会产生正确的程序,而另一个词汇翻译会。

第四次操作(编译失败)

相同的“最长可能翻译”规则解析i++++ii, ++, ++i这不是一个有效的表达式(因为++操作的结果是一个值,而不是一个变量)。

于 2014-02-25T09:43:21.853 回答
13

+is an operator, and ++is an operator, but + +is not -+ +解释为两个+s,而不是一个++。所以空间迫使你的代码被不同地解释。

+既是一个将两个数字相加的二元运算符,也是一个不改变一个数字的一​​元运算符(它的存在只是为了与一元运算符保持一致-)。

如果我们使用add而不是 binary +no-change而不是 unary +,而increment不是++then 可能会更清楚。

int j=i+ + +i变成int j = i add no-change no-change i;.
int k=i++ +i;变成int k=i increment add i;.
我怀疑int k = i+++i;也变成int k = i increment add i;了,但我没有用语言规范检查过。

于 2014-02-25T09:35:39.123 回答