[英]Question about C programming
int a, b;
a = 1;
a = a + a++;
a = 1;
b = a + a++;
printf("%d %d, a, b);
輸出:3,2
第3行和第5行有什么區別?
你在做什么是不確定的。
您無法更改將要分配給的變量的值。
您也不能更改具有副作用的變量的值,並且還嘗試在同一表達式的其他位置使用相同的變量(除非有序列點 ,但在這種情況下沒有)。 +的兩個參數的求值順序不確定。
因此,如果兩行之間存在差異,則是由於兩個原因而未定義第一行,而僅出於一個原因而未定義第5行。 但是關鍵是第3行和第5行都未定義,並且做錯了。
您在第3行上的操作未定義。 C ++具有“序列點”(通常由分號分隔)的概念。 如果您在每個序列點修改一個對象超過一次,則它是非法的,就像您在第3行中所做的一樣。正如C99的6.5節所述 :
(2)在上一個序列點與下一個序列點之間,對象的存儲值最多只能通過對表達式的求值來修改。 此外,先驗值應只讀以確定要存儲的值。
由於第二句,第5行也未定義。 讀取a
可獲得其值,然后將其用於a++
中的另一個賦值。
第3行未定義,第5行未定義。
正如Prasoon正確指出的, 兩者都是UB。
由於以下原因,未定義簡單表達式a + a++
:
+
不是一個序列點,因此每個操作數的副作用可能以兩種順序發生。 a
最初是1
。 可能出現以下兩種[明智的]情形之一:
首先計算第一個操作數a
a)其值1
將存儲在寄存器R
。 沒有副作用發生。
b)計算第二個操作數a++
。 它還求值為1,並加到相同的寄存器R
。 作為副作用,所存儲的值a
被設置為2。
c)當前在R
中的加法結果寫回到a
。 的最終值a
是2。
首先計算第二個操作數a++
。
a)將其求值為1
並存儲在寄存器R
。 的存儲值a
遞增到2
。
b)讀取第一個操作數a
。 現在它包含值2
而不是1
! 它被添加到R
。
c) R
包含3
,並且此結果寫回到a
。 現在加法的結果是3
,而不是2
,就像我們第一種情況一樣!
簡而言之,您完全不必依賴此類代碼。
a++
是一個后綴運算符,它獲取a的值然后對其進行遞增。
因此,對於第2,3行:
a = 1
a = 1 + 1,a遞增。
a變為3 (注意,這些操作的執行順序在編譯器之間可能會有所不同,並且a也很容易變為2)
對於第4,5行:
a = 1
b = 1 + 1,a遞增。
b變成2,a變成2。 (由於不確定的行為,b可能也變成a ++中的3在a之前被處理)
請注意,除了了解后綴運算符的工作原理以外,我真的不建議您使用此技巧。 這是未定義的行為 ,使用不同的編譯器進行編譯時將獲得不同的結果
因此,這不僅是不必要的混淆方式,而且是一種不可靠且最差的做法。
編輯 :還有其他人指出,這實際上是未定義的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.