簡體   English   中英

有關C編程的問題

[英]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++

  1. 運算符+不是一個序列點,因此每個操作數的副作用可能以兩種順序發生。
  2. a最初是1
  3. 可能出現以下兩種[明智的]情形之一:

    1. 首先計算第一個操作數a

      a)其值1將存儲在寄存器R 沒有副作用發生。

      b)計算第二個操作數a++ 它還求值為1,並加到相同的寄存器R 作為副作用,所存儲的值a被設置為2。

      c)當前在R中的加法結果寫回到a 的最終值a是2。

    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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM