2014-02-12 47 views
2

本主題在很多情況下都經過了深入討論。當我搜索並閱讀一些帖子時。後來發帖讓我很困惑。關於整數推廣的問題仍然存在問題,C中的轉換問題

Signed to unsigned conversion in C - is it always safe?

以下是原來的問題。

unsigned int u = 1234; 
int i = -5678; 
unsigned int result = u + i; 

答案簡單地引用了「6.3.1.8通常的算術轉換」第3點,即

否則,如果具有無符號整數類型的操作數的秩大於或等於的秩另一個操作數的類型,則帶符號整數類型的操作數將轉換爲具有無符號整數類型的操作數的類型。

但是,如果我的理解是正確的,整數推廣應考慮「通常的算術轉換」以前做過

而規則是

如果int可以表示原始類型的所有值,該值被轉換爲int。否則,它被轉換爲一個無符號整數。這些轉換規則被稱爲積分促銷

所以,這意味着除了完成與類型的符號整數unsigned int類型。如果將負值分配給unsigned int結果,則轉換爲較大值。

我對自己的理解有點不自信。有沒有人對這個帖子有類似的困惑?

歡迎任何回覆或評論。感謝提前!

傑夫

回答

3
unsigned int result = u + i; 

我們有添加劑經營者。具有算術類型操作數的加法運算符首先執行通常的算術轉換。

常見的算術轉換分兩步完成:

首先整數整數促銷應用到每個操作數:

  • u沒有晉升爲int,因爲它是unsigned int
  • i已經int ,不需要推廣到int

由於操作數實際上有一個等於int的類型等級,所以不執行整數升級。

其次,將操作數轉換爲常見類型。常見的類型是unsigned int

  • u已經unsigned int
  • i是類型int並轉換成unsigned int

通常的算術轉換加入unsigned int型的兩個值並分配給result結果之後。

+0

看來我對上面的帖子中的第二條規則有點誤解。我的理解是int可以表示u的值,所以,應該將u提升爲int,而不是* unsigned int *。這是錯的嗎? – Poor

+0

@第一步是整數升級,這裏升級的操作數在升級之前和之後是相同類型的。在第二步中,C說(在c99中,6.3.1.8p1)*「如果具有無符號整數類型的操作數的秩大於或等於另一個操作數類型的秩,那麼具有有符號整數類型的操作數是轉換爲具有無符號整數類型的操作數的類型「*和'unsigned int'和'int'類型的轉換等級相同。這就是爲什麼'i'在第二步轉換爲'unsigned int'的原因。 – ouah

+0

@Poor對你更清楚嗎? – ouah

0

我將用十六進制表示,以解釋該問題...

假設一個int變量的大小爲32位:

  • 1234 = 0x000004D2
  • - 5678 = 0xFFFFE9D2

在做a+b時,它並不重要他們每個人的表現如何(signedunsigned)。如果添加了兩個值以上,結果存儲在一個int變量,然後將持有0xFFFFEEA4的的值,而與每個操作數的符號的

  • 如果輸出變量是signed,那麼它(在其他操作中)將被視爲-4444。
  • 如果輸出變量爲unsigned,那麼它將被視爲(在其他操作)爲4294962852.
+1

我相信這是不正確的。這對於1的補碼或符號/幅度的系統無效。 – user694733

2

但是,如果我的理解是正確的,整數推廣應考慮「通常的算術之前完成轉換」。

正確的,但整數提升,由整數提升規則的定義,只適用於小整數類型,如char和短。你只引用了該段的一半,這可能會讓你感到困惑。讓我舉的那款作爲一個整體:

C11 6.3.1.1/2

下可以在表達式中使用的任何地方可以使用int或unsigned INT:

  • 整數轉換等級小於或等於 int和unsigned int的整數類型的對象或表達式(int或unsigned int除外)。

  • 類型爲_Bool,int,signed int或unsigned int的位域。

如果int可以表示原始類型(如由寬度限制 ,對於一個位字段)的所有值,該值被轉換爲int; 否則,它被轉換爲一個unsigned int。這些被稱爲 整數促銷。所有其他類型均以整數 促銷活動不變。

所以整型提升並不適用於intunsigned int,因爲他們不具備較小的轉換軍銜。

所以,這意味着添加完成的類型的signed int比unsigned int。當給unsigned int結果賦一個負值時,轉換爲一個較大的值。

不正確,因爲通常的算術轉換,所以添加在usigned int上完成。

+0

+1刪除我的答案,因爲它只回答了一半的問題。這個答案就是這一切。 – user694733

+0

@Lundin你是對的,我忽略了整數提升的條件,或者沒有完全理解這個條件的含義。陷阱語句是*(int或unsigned int除外)*。 – Poor