这是一个有趣的计算 3 个加号相连。那么到底是如何结合的呢?是按照 i + (++j)来运算还是按照(i++) + j 来运算呢?

  这个问题在类似于 C / C++中讨论是没有多大意义的因为 C / C++依赖于实现的硬件结构不同的环境结果也会不同。不过在 Java 中这个结果是固定的不受其运行的硬件环境与平台所影响.

  到底按照什么顺序运算呢写个程序来测试下吧。

  【例】++的结合

wKiom1cGGuqzQzfiAABLe0YwS6c548.png

  如果结合为

wKioL1cGG5jjlQYdAAAGxFLj6FM332.png

  则 i 的值会加 1结果 k 的值为 30如果结合为

wKiom1cGGuuQGOj3AAAHOAUgFRc608.png

  则 j 的值会加 1结果 k 的值为 31。程序运行结果如下

wKioL1cGG5jze755AAARiMcJRN0968.png

  从结果可知结合的顺序为前者也就是说

wKioL1cGG5mD6mPEAAAGmmVbAsE206.png

  相当于

wKiom1cGGyuTaDTKAAAIXVgnBGI548.png

  为了更加清晰这里使用括号。

  贪心规则

  这种结合性要归根于编译器的贪心规则也就是说在分析符号的时候编译器会尽可能多地结合有效的符号例如上面的表达式

wKiom1cGGyvRN-ozAAAGmmVbAsE276.png

  “ +”与“ ++”都是有效的符号但是“ +++”不是有效的符号因此经过分析后最终将表达式解析为

wKioL1cGG9mydKpqAAAGxFLj6FM047.png

  不过编译器极度“贪心”其只管尽可能多地结合有效的符号而不管这样结合是否符合语法的规则例如表达式

wKiom1cGGyyRoBZoAAAHCd8l8TE073.png

  本来我们的原意是 a 减去b即

wKiom1cGGyyAvLREAAAHuF3PAxA737.png

  但是如果之间不使用空格(或其他符合语法规则的空白分隔符)或括号进行分隔经过分析之后因为符号“ –”是有效的符号所以会组合在一起这样结构就划分为

wKioL1cGHCGiWhh4AAAHUZzt4bw470.png

  这当然不符合语法规则所以编译器也会无情地产生了编译错误。

  为何贪心

  也许读者会问为什么要使用这种贪心的方式来分析字符呢?这样有什么好处呢?相信看过下面的例子你就会明白了。

  【例】 贪心的解释。

wKioL1cGHCHwfcCrAACUbP64els876.png

  程序就是输出若干个八进制转义字符而已貌似与贪心规则根本没有关系。如果这样想的话那你错了请看运行结果

wKioL1cGHCHz109tAAAd1tjd5z0208.png

  想想看 为什么 String 对象 “ \17”的长度为 1“ \171”的长度也为 1 呢?还有 为什么 “ \171”不打印出“ \17”的转义字符“ ”并与“ 1”连接成

wKioL1cGHCLTTFKKAAAGazcb5YQ673.png

  而是打印出

wKiom1cGG3Ty8dScAAAFjnwjwdM663.png

  呢?那就是因为贪心规则编译器会尽可能多地对有效字符进行结合否则转义字符将失去作用。对于“ \1717”与“ \431”会按两个字符来处理因为这两个数值都超过了八进制转义字符的取值范围( \0\377)因此“ \1717”会解析为“ \171”与“ 7”而“ \431”会解析为“ \43”与“ 1”。

  总结

  编译器在分析字符时会尽可能多地结合有效字符。并且“过度”地贪心而不管这种结合方式是否符合语法规则。

  贪心规则是有用的因为这样可以对转义字符等进行特殊处理。


本文出自柠檬派http://www.lemonpai.com请务必保留此出处否则将追究法律责任