不同的间距如何影响一元算子?

Rav*_*ara 27 java unary-operator

谁能解释我不同的间距如何影响一元算子?

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
Run Code Online (Sandbox Code Playgroud)

.

Jon*_*eet 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

int k = 1;
System.out.println((k++) + k);
Run Code Online (Sandbox Code Playgroud)

第一次操作

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

第二次操作

这个很简单:它就像它读取的那样,一个后缀++运算符后跟一个二元+运算符(不是一元+运算符,+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
Run Code Online (Sandbox Code Playgroud)

正如你所看到的那样,它k1已经增加而不是k2.

其原因k+++k被解析为的令牌k,++,+,k是由于该JLS的第3.2节,其包括:

每个步骤都使用尽可能长的翻译,即使结果最终没有形成正确的程序而另一个词汇翻译也会如此.

第四次操作(编译失败)

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

  • 我不确定运算符优先级是解释第三行的原因.我怀疑它是词法分析器中实现的最大munch规则的结果:当它看到一系列字符时,它会尝试构造它可以的最长令牌.如果是一系列加号,那将是一个'++'标记. (4认同)

use*_*751 13

+是一个运算符,并且++是一个运算符,但+ +不是 - + +被解释为两个+,而不是一个++.因此,空间强制您的代码被不同地解释.

+是一个二进制运算符,它添加两个数字和一元运算符,它不会改变一个数字(它只存在与一元运算-符的一致性).

如果我们用add,而不是二进制+,no-change而不是一元+,并increment代替++,那么它可能会更清晰.

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;但我还没有用语言规范来检查.

  • 重要的是,`+ +`被解释为二进制`+`运算符,后跟一元`+`运算符(我相信).这使得"添加添加"解释比"添加一元加一元加"更有帮助.所以`int j = i + + + i`相当于`int j = i +(+(+ i)); (8认同)
  • @dasblinkenlight通过编写令人困惑的代码感到困惑.研究奇怪的边缘情况对于了解事物的确如何运作非常有用.;) (2认同)