作者LPH66 (f0VMRgEBA)
看板java
标题Re: [问题] 关於一个小程式的问题
时间Mon Feb 17 23:48:13 2014
推文有点久所以回一篇
※ 引述《CrystalNik (水晶尼克)》之铭言:
: public static void main(String args[])
: {
: x--;
: myMethod();
: System.out.println( x + y + ++x );
: }
: public static void myMethod()
: {
: y = x++ + ++x ;
: }
事情是这样的
y = x++ + ++x; 在 java 里的动作依序如下:
(0) 首先一开始 x 是 -1;
(1) 求 x++ 的值 (为 x 目前的值) 并带附加效应让 x 的值加一
於是求得的值是 -1, x 的值成为 0;
(2) 求 ++x 的值 (为 x 目前的值加一) 并带附加效应让 x 的值加一
於是求得的值是 1, x 的值成为 1;
(3) 做加, 把 (1) 跟 (2) 求得的值加起来, 故这时 y 的值成为 0;
所以 myMethod 做完之後 x 的值是 1, y 的值是 0
回到 main 之後, System.out.println( x + y + ++x ); 又依序做了这些事:
(4) 求 x 的值, 得 1;
(5) 求 y 的值, 得 0;
(6) 做第一个加, 把 (4) 跟 (5) 求得的值加起来, 得 1;
(7) 求 ++x 的值 (为 x 目前的值加一) 并带附加效应让 x 的值加一
於是求得的值是 2, x 的值成为 2;
(8) 做第二个加, 把 (6) 跟 (7) 求得的值加起来, 得 3;
(9) 呼叫 println 印出 (8) 的结果
所以最後印出来的是 3
---
JLS 15.7 节对这部份的规定很详细
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.7
二元运算子会隔开其两个运算元的效应启动跟结算时间
一定是左边完全算完效应也结算了右边才开始动作
(1) (2) (7) 的结果会是这样就是这个规定的原因
不过实际在写程式请不要这样写, 会出大事....
--
LPH [acronym]
= Let Program Heal us
-- New Uncyclopedian Dictionary, Minmei Publishing Co.
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 123.195.35.61
1F:推 CrystalNik:好详细!! 懂了!! 偷偷问一下为什麽实际写程式不建议这 02/17 23:58
2F:→ LPH66:其实主要是防止脑袋打结 XD 另外 C/C++ 不规定结果会如何 02/18 00:02
3F:推 PsMonkey:建议也看一下 z-3-4-8 02/18 00:17
4F:→ danny8376:真要这样搞也多打几个括号 不然接手的会恨死你(含自己) 02/18 01:44
5F:→ andymai:为何不建议?那就要反问平常会这样写?人生没有必要把时间花 02/18 01:59
6F:推 pupuliao:有人真的这样写code ? 是有病还是自谑? 02/18 03:05
7F:推 pupuliao:这顶多拿来理解规则,没人真拿来实做吧.... 02/18 03:08
8F:→ Killercat:C++99时代对於这个都是没有定义 看编辑器 11就不知了 02/18 12:22
9F:→ Killercat:所以a++ + ++a这种会爆浆 另外","运算子也是常出包的点 02/18 12:23
10F:→ Killercat:还有一个很有趣的例子是x = ++x; 在C++一样会爆浆 :D 02/18 12:25
11F:→ ssccg:应该不是问为什麽不建议,而是为什麽会想这样写吧? 02/18 14:01
12F:推 justin761002:推,长知识了! 02/19 04:51
13F:→ justin761002:程式码要以易读、好维护为原则,这东西显然不易读啊! 02/19 04:55
14F:推 fonz:详细推 02/19 12:38
15F:→ Killercat:这是夸张的例子,事实上恶毒的例子的话,很多很难察觉的 02/19 13:03
16F:推 kiwatami:通常只有快离职才会这样写吧(误) 02/23 19:53
17F:→ danny8376:应该是写完就快离职了吧(? 02/24 09:32
18F:→ AnyaAlstreim:为了工作机会保障... 02/24 20:43