2013-02-11 124 views
3

我知道較低的數據類型被澆鑄到更高的數據類型(如int - >無符號整型 - >浮 - >等),但我不能確定如下:C++從無符號的隱式數據類型轉換爲帶符號的

int var = 5u - 10; // var = -5 
auto var = 5u - 10; // var = 4294967291 

5u是無符號的,但在第一種情況下,爲什麼-10(有符號整數)沒有轉換爲無符號值,而在第二種情況下呢?在第一種情況下,有符號值不會轉換爲無符號值,對我來說這是奇數

+3

根據C標準,'5u-10'計算爲'unsigned int'。 – sgarizvi 2013-02-11 17:51:57

+3

C或C++?選一個。 – 2013-02-11 17:54:41

+7

在這兩種情況下,減法的結果都是'無符號',但在第一種情況下,結果將轉換爲目標類型。因此'4294967291'被轉換爲'-5' – Praetorian 2013-02-11 17:55:12

回答

3

沒有「有符號整數字面量」:5u - 10實際上是從5u中減去10。

(的減法)的結果是無符號的,並進入溢出,給出作爲結果(4294967291 = 2 -5)

第一條語句初始化「比飛越0少5個號碼」一個int,因此無符號編譯時間常數被重新解釋爲int。結果是正確的(-5),因爲你的硬件使用二進制補碼算術。 (-5和4294967291是相同的32位模式)

第二條語句初始化一個變量,該變量的類型由文字推斷。它是unsigned

2

首先,因爲您使用的是auto,編譯器會在第二個示例中選擇unsigned

有符號和無符號數字在內部以相同的方式存儲。這只是數字在打印時被解釋的方式,它會產生變化[並且在比較中,因爲'負'有符號數字小於0,其中無符號數字不能小於零] - 簽名數字被檢查如果它們是「負值」,並打印爲負號和否定的原始號碼。無符號數字只被視爲打印時內部表示形式變成的內容。

所以你看到的值只是相同數字的兩個不同表示 - 分別爲有符號和無符號。

2

的右側你的例子完全工作在的域中,無符號的類型。即你的兩個表情5u - 10表現相同,這並不奇怪,因爲它們是相同的。在這兩種情況下,都沒有轉換爲int(因爲您似乎錯誤地假設)在5u - 10表達式中。

表達式5u - 10始終在無符號類型的域中進行評估並生成等於UINT_MAX + 1 - 5的無符號結果。在第一次初始化時,您嘗試將該值強制爲int類型的變量,這會導致實現定義的行爲發生溢出。在你的情況下,你的實現表現爲var獲得值-5。換句話說,在var中以-5結尾的事實在抽象C++語言領域沒有明確的解釋。你觀察到的結果只是你的編譯器的一個怪癖。在其他一些編譯器中,第一次初始化可能會在var中產生不同的值。

在第二種情況下,表達式的類型(也就是unsigned)變成變量的類型,該變量使用無符號值進行初始化,沒有任何溢出。

1

在C和C++中,在絕大多數情況下,表達式的類型是從表達式本身確定的,而不考慮表達式的上下文。

int var = 5u - 10; 

5uunsigned int類型; 10類型爲int-運算符的規則會導致int參數轉換爲unsigned int,從而使表達式等效於5u - 10u。結果是UINT_MAX + 1 - 10,這是一個非常大的數字。初始化將其從unsigned int隱含轉換爲signed int。由於該值(幾乎肯定)不能表示爲int,因此轉換的結果是實現定義的。在幾乎所有現有的實現中,轉換隻是重新解釋無符號表示,就好像它是一個有符號值,導致-5。 (這適用於使用二進制補碼錶示負值的系統;由此產生的有符號/無符號轉換的簡單性是二進制補碼廣泛使用的原因之一。)

請注意,它不可能用於var具有值4294967291; int可以容納在您的系統上的最大值是(可能)2147483647

auto var = 5u - 10; 

5u - 10作爲評估之前以同樣的方式,導致UINT_MAX + 1 - 5,或者4294967291您的系統上的unsigned int結果。 auto表示var採用表達式的類型unsigned int,因此不執行轉換。 (在16位int的系統,其結果將是65531

在回答你的問題,不斷10int轉換爲unsigned int在這兩種情況下

相關問題