2016-12-28 89 views
0
int x=3, y=4, n=0; 
int n = x * y/--x; 

此代碼計算n爲6,但我認爲它會是4;因爲--x是預遞減運營商,擁有超過*/更高的優先級所以這將是2 * 4/2我認爲這是2*4,而不是作爲3*4x已經遞減,所以我缺少什麼嗎?同樣的問題已被問到here,但答案是PHP特定的。在變量分配之前,前/後增量操作符是如何操作的?

+0

http://stackoverflow.com/questions/2371118/how-do-the-post-increment-i-and-pre-increment-i-operators-work-in-java – kbunarjo

+0

@kbunarjo那並不是」回答我的問題。 –

+0

x在得到-x之前已經被評估,因此x仍然是3. – kbunarjo

回答

2

如果我們編譯這段代碼,然後使用ILDASM檢查它,我們得到了以下說明(已轉換使用https://en.wikipedia.org/wiki/List_of_CIL_instructions):

IL_0000: nop   // I compiled in debug mode, this does nothing 
IL_0001: ldc.i4.3  // Push 3 onto the stack as int32. 
IL_0002: stloc.0  // Pop a value from stack into local variable 0. 
IL_0003: ldc.i4.4  // Push 4 onto the stack as int32. 
IL_0004: stloc.1  // Pop a value from stack into local variable 1. 
IL_0005: ldloc.0  // Load local variable 0 onto stack. 
IL_0006: ldloc.1  // Load local variable 1 onto stack. 
IL_0007: mul   // Multiply values. 
IL_0008: ldloc.0  // Load local variable 0 onto stack. 
IL_0009: ldc.i4.1  // Push 1 onto the stack as int32. 
IL_000a: sub   // Subtract value2 from value1, returning a new value. 
IL_000b: dup   // Duplicate the value on the top of the stack. 
IL_000c: stloc.0  // Pop a value from stack into local variable 0.  
IL_000d: div   // Divide two values to return a quotient or floating-point result. 
IL_000e: stloc.2  // Pop a value from stack into local variable 2. 
IL_000f: ret   // Return from method, possibly with a value. 

這表明該表達式求值由左到右,即使--x先於*/

這也記錄在C#語言規範(第7.3節算):

運算符的計算表達式中的順序由所述 優先級和結合操作符(§7.3.1確定)。

表達式中的操作數從左到右計算。例如,對於 示例,在F(i)+ G(i ++)* H(i)中,方法F使用i的舊值 調用,然後使用舊值i調用方法G,最後使用方法H用新的i值調用。這是與運營商優先級無關的 。

+0

您可以舉一個LTR評估的例子,不要使用函數,只是運營商? –

+1

你的例子是一個。操作數被評估爲LTR('x',然後'y',然後'--x')。_operations_的順序由運算符優先級確定,但_operands_本身從左到右進行評估。 –

+0

斯坦利寫的東西正是我要說的。操作數和操作符有所不同。運算符優先級定義了操作數的處理順序,但在處理表達式之前,所有運算符都將從左到右進行求值,而不考慮表達式中的運算符。 – mstaessen