2010-01-17 91 views
1

爲什麼對於第二打印下面的代碼問題有關遞增運算符

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

輸出2 兩次,而不是3?

請問有人可以提供一些啓示嗎?

謝謝。

+14

應該指出,在現實世界中,你絕不應該這樣編碼。決不。 – missingfaktor 2010-01-17 13:03:59

+0

@Grey:是的,只是爲了解決這個問題 – Ricky 2010-01-17 13:47:05

回答

4

如果您意識到++的工作原理如下(僞代碼):

funC++(ref a) 
{ 
    int b=a; 
    a=a+1; 
    return b; 
} 

那麼它都有道理。

+1

對於Java程序員來說''ref'有點不重要,你知道;) – 2010-01-17 13:02:21

+0

嗯。對於那些不瞭解ref部分的人,我試圖說明,通過這個函數,在(a)中傳遞的變量值在呼叫站點發生了變化。 – spender 2010-01-17 13:04:58

+0

很清楚! spender – Ricky 2010-01-17 13:53:16

3

它可能看起來像我應該在3最後。

但是,如果你看看錶述更加緊密

i += (i++) 

等於

i = (i + (i++)) 

是,在這種情況下,1 + 1。

i ++的副作用是i = i + 1 = 1 + 1 = 2,因爲您可能已經預料到了,但是i的值在賦值之後被覆蓋。

-1
1 + 1 == 2. 

因此:

i + i == 2 

i += i == 2 

然後

i += i++ == 2 

漂亮的直線前進。

+2

恐怕增量後運算符在這裏沒有真正解釋。 – bryantsai 2010-01-17 13:30:11

2

我不知道Java字節碼的語法非常好,但還沒有根據我在字節級的代碼會是這個樣子:

int i = 1; // iconst_1: variables { }, stack {1} 
      // istore_1: variables {1}, stack { } 
i += i++; // iload_1:  variables {1}, stack {1} 
      // iinc 1, 1: variables {2}, stack {1} 
      // iadd:  variables {2}, stack {2} ...Note that here 1 gets added to the value on stack 
      // istore_1: variables {2}, stack {2} ...Here the variable value will overwrite the stack value 

我覺得這個解釋你得到很好的輸出。 :-)

專家,請糾正我,如果我錯了......

2

我不認爲這是不知道的後綴一元運算符(EXPR ++)是如何工作的問題。評估報表的順序是造成混淆的原因。

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

所以最後一條語句是一樣的順序如下兩條語句:

i++; // i is now 2 for the rest of this statement and the program 
i = 1 + 1; // i is assigned again 

所以後綴運算符是第一,但隨後整條生產線進行評估,但使用的前值評估一世。

所以,用一個例子來使這更清楚:

int i = 2; 
System.out.println(i += i++); // Output: 4 
System.out.println(i); // Output: 4 

而另一個例子:

int i = 2; 
System.out.println(i = i + i++ + i--); // Output: 7 
System.out.println(i); // Output: 7 

第二行分配。第一爲2時,下一也爲2,但現在的第三是3,因爲我+ +已經改變的的值。從之前的情況來看,我 -將不會對我產生任何影響,因爲它將被重寫爲i = 2 + 2 + 3

int i = 1; 
System.out.println(i = i++ + i); // Output: 3 
System.out.println(i); // Output: 3 
+0

很gd的解釋。 – Ricky 2010-01-18 08:15:47