我對C#編譯器如何處理前後增量和遞減有點困惑。C#前期和後期增量混淆
當我的代碼如下:
int x = 4;
x = x++ + ++x;
x
將具有值10之後。我認爲這是因爲預增量設置爲x
至5
,這使得5+5
的計算結果爲10
。然後後增量將更新x
至6
,但不會使用此值,因爲那麼10
將被分配到x
。
但是,當我代碼:
int x = 4;
x = x-- - --x;
然後x
將2
之後。任何人都可以解釋爲什麼這是事實嗎?
我對C#編譯器如何處理前後增量和遞減有點困惑。C#前期和後期增量混淆
當我的代碼如下:
int x = 4;
x = x++ + ++x;
x
將具有值10之後。我認爲這是因爲預增量設置爲x
至5
,這使得5+5
的計算結果爲10
。然後後增量將更新x
至6
,但不會使用此值,因爲那麼10
將被分配到x
。
但是,當我代碼:
int x = 4;
x = x-- - --x;
然後x
將2
之後。任何人都可以解釋爲什麼這是事實嗎?
x--
將是4,但會3日在--x
的時刻,所以它會結束爲2,那麼你就必須
x = 4 - 2
順便說一句,你的第一個案例將是x = 4 + 6
這裏是一個小例子,將打印出值爲每個部分,也許這樣你會更明白:
static void Main(string[] args)
{
int x = 4;
Console.WriteLine("x++: {0}", x++); //after this statement x = 5
Console.WriteLine("++x: {0}", ++x);
int y = 4;
Console.WriteLine("y--: {0}", y--); //after this statement y = 3
Console.WriteLine("--y: {0}", --y);
Console.ReadKey();
}
此打印Ø UT
x++: 4
++x: 6
y--: 4
--y: 2
我認爲對於++ + ++情況的解釋是錯誤的:X
的命令...........值
.... ..............未定義
INT X = 4 .......... 4
X ++ ........... .... 5(第一個被加數是4)
++ X ............... 6(第二被加數是6)
X = summand1 + summand2 ..4 + 6 = 10
類似的用於解釋 - - - 情況下是
命令........... X
的值..................未定義
INT X = 4 .......... 4
X --............... 3(subtactor是4)
--x ............... 2(減數爲2)
x =減法 - 減數。4-2 = 10
我完全不明白你的回答,對不起。 – 2011-12-20 13:41:54
@phresnel我糾正了答案中的一些錯誤。他的基本意思與你接受的答案一樣:我們實際上得到了10,因爲我們加了4和6; 2是4和2之間的差異。 – phoog 2011-12-20 19:42:41
讓我們看看那個會從該語句生成
IL_0002: ldloc.0
荷載x的壓入堆棧的值IL。堆棧=>(4)
IL_0003: dup
複製堆棧中最頂端的項目。堆棧=>(4,4)
IL_0004: ldc.i4.1
將1推入堆棧。堆棧=>(1,4,4)
IL_0005: sub
減去兩個最高值並將結果推送到堆棧。堆棧=>(3,4)
IL_0006: stloc.0
將堆棧的最高值存回x。堆棧=>(4)
IL_0007: ldloc.0
將x的值加載回棧中。堆棧=>(3,4)
IL_0008: ldc.i4.1
將值1加載到堆棧上。堆棧=>(1,3,4)
IL_0009: sub
減去兩者。堆棧=>(2,4)
IL_000A: dup
重複頂部值=>(2,2,4)
IL_000B: stloc.0
商店頂部值返回至x。堆棧=>(2,4)
IL_000C: sub
減去兩個最高值。堆棧=>(2)
IL_000D: stloc.0
將此值存回x。 X == 2
在這個例子中,
int x = 4;
x = x++ + ++x;
你可以打破它想:
x = 4++; which is = 5
x = 4 + ++5; which is 4 + 6
x = 10
同樣,
int x = 4;
x = x-- - --x;
這裏,
x = 4--; which is = 3
x = 4 - --3; which is 4 - 2
x = 2
簡而言之,可以說,替換x的當前值,但對於每個++或 - 從x中添加/減去一個值。
最有趣的事情是,您將得到與C++ .Net編譯器完全不同的答案。
int x = 4;
x = x++ + ++x; // x = 11
x = 4;
x = x-- - --x; // x = -1
當然的結果之間的差異是由不同的語義確定 - 它似乎正常。但是,儘管理解了兩個.net編譯器不以類似的方式表現這種基本的東西,我也感到困惑。
在C++(不是Microsoft的非C++版本的C++之一)中,在完整表達式結束之前多次修改變量會產生未定義的行爲。 – 2011-12-20 13:40:56
這與* parse *沒有任何關係。它與兩種語言關於順序點的不同允許語義有關。 – 2011-12-20 16:51:36
從您的評論:
我認爲,後和預增量後執行/完整的代碼行的評估之前 - 但他們執行後/每個項目的表達式中的評估之前。
你的誤解是非常普遍的。請注意,在某些語言(如C)中,不會在副作用變爲可見時指定它,因此它是合法的,但並非必需的,因爲您的語句在C中爲true。
這不是C#中的情況;在C#代碼表達式的左側副作用始終觀察代碼之前發生在右側執行(從單個線程;在多線程方案所有的賭注都關閉。)
對於更詳細的什麼樣的增量運營商在C#做的說明,請參閱:
What is the difference between i++ and ++i?
有到我寫這個經常被誤解的話題的文章非常多的其他鏈接存在。
好問題!我們已經學會了從不寫代碼,你必須考慮它可以做什麼,但它會做什麼。 – RvdK 2011-12-20 09:32:30
任何寫這樣的代碼的人都應該被取出並拍攝。 'x = x ++ + ++ x;'...沒有任何藉口。 – 2011-12-20 09:33:13
這只是一個「學術」問題 - 我永遠也不會寫這樣的代碼:-) – Schweder 2011-12-20 09:41:24