簡體   English   中英

C 比較char和int

[英]C comparison char and int

在下面的代碼塊中,7 的 if 語句中發生的隱式轉換是什么? 我本來以為它最終會是 (0x98 <= 0x07) 但當條件計算為真並且 DoMyStuff 被調用時,情況並非如此。

char minstogo = 0x98;
if(minstogo <= 7) {
   DoMyStuff();
}

每當你在兩個不同類型的整數操作數之間有一個二元運算符( + - * / % << >> & | ^ == != < <= > >=之一)時,這兩種類型會先轉換為通用類型操作被執行。 決定轉換類型的規則是(來自 C99 標准的第 6.3.1.8 節):

如果兩個操作數具有相同的類型,則不需要進一步的轉換。

否則,如果兩個操作數都具有帶符號的 integer 類型或都具有無符號的 integer 類型,則具有較小 integer 轉換等級的操作數將轉換為具有較大等級的操作數的類型。

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

否則,如果有符號integer類型操作數的類型可以表示無符號integer類型操作數類型的所有值,則將無符號integer類型操作數轉換為有符號integer類型操作數類型。

否則,兩個操作數都轉換為無符號 integer 類型,對應於帶符號 integer 類型的操作數的類型。

在這種情況下, char可以是有符號或無符號的 integer 類型——它的符號是實現定義的。 不過,幸運的是,假設您使用的系統中char是 8 位且int至少是 16 位,則int可以表示char的所有可能值,無論char是否帶符號。

如果char是有符號的,則適用上面的第二段,因此兩個操作數都轉換為int (具有更高級別的類型;級別的定義方式有些復雜,但它本質上等同於該類型的位大小)。 由於 0x98 作為帶符號的char為負數,因此它被轉換為 integer -104,然后小於 7。

相反,如果char是無符號的,則適用第四段。 unsigned char將作為int轉換為 152,它大於 7。

永遠不要依賴char被簽名或未簽名。 如果您需要具有特定符號的 8 位整數,請顯式使用signed charunsigned char ,或使用 C99 類型int8_tuint8_t ,定義為 int <stdint.h>

很容易被 integer 促銷規則引起的細微錯誤所困擾。 我強烈建議您始終使用-Wall和 gcc 進行編譯,這將警告您有符號整數和無符號整數之間的比較,這通常是導致錯誤的原因。

這里可能發生的情況是 char 是一個帶符號的值,因此 0x98 注冊為負數。 因此它小於 7

同樣在這種情況下,7 將在 go 下不進行轉換。 相反,char 將被擴展為與 7 相同的整數類型,然后進行比較。

0x98 是 152。

由於您聲明了“char”而不是“unsigned char”,因此您試圖將 152 分配給范圍為-128 - 127的類型。

這將溢出,並給你一個負數,它將 < 7 (0x07)。

將 chars 表示為八位字節,將 minstogo 設置為 0x98 是二進制值 10011000。設置了符號位,它是一個負值 integer。 您可能需要一個 unsigned char 以便測試評估為 false。

它的計算結果與0x98 <= 7相同,除非平台的char類型默認為有符號且CHAR_BIT為 8。在這種情況下, minstogo的值為負且minstogo <= 7為真。

使用當前設置的編譯器,char 是有符號類型:並且因為設置了其值的高位 (0x80),所以該值為負。 當 minstogo 被加寬時,該負號被保留(通過符號擴展),因此 minstogo 被加寬為小於 7 的負值 integer(例如 0xFF98)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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