2015-01-01 83 views
0

所以最近,我讀了一個關於C,char/unsigned char/signed char中三種不同類型的問題。我現在遇到的問題並不是我迄今爲止所經歷過的(我的程序在所有測試過的計算機上都能正常工作,並且只針對小端(基本上所有使用Windows/Linux的現代臺式機和服務器都適用?)。我經常重複使用char我爲定義一個「字符串」(當然不是一個真正的字符串)作爲臨時變量定義的數組,例如,不是將另一個字符添加到堆棧中,而是重用像array [0]這樣的成員之一。事實上,一個char總是簽署,直到今天我讀它實際上取決於實現。如果我現在有一個char和我分配一個負值,會發生什麼?C cast和char signedity

char unknownsignedness = -1; 

如果我寫的

unsigned char A = -1; 

我認爲C風格的演員將簡單地重新解釋位和A表示爲無符號類型的值變得不同。我認爲這些C型表演只是對位的重新解釋嗎?我現在指的是簽署< - >無符號轉換。

所以如果一個實現有char作爲無符號,我的程序會按預期停止工作嗎?就拿最後一個變量,如果我現在做

if (A == -1) 

我現在比較一個無符號字符到符號的字符值,所以會這樣簡單地比較不關心是否帶符號位還是將返回false,因爲顯然不能是-1?我很困惑在這種情況下會發生什麼。這也是我最關心的問題,因爲我經常使用這樣的字符。

+2

什麼鑄造?沒有任何地方鑄造。如果要存儲二進制(非字符)數據,請使用更好的(IMO)'int8_t'或'uint8_t'標準類型。 –

+0

我的實現不支持C99,我認爲int8_t是該版本 – user209347

+0

如果我將一個有符號的值賦給一個無符號的值,會不會有轉換?或者只有在數據大小不匹配的情況下才會投射? – user209347

回答

4

安全下面的代碼打印No

#include <stdio.h> 

int 
main() 
{ 
    unsigned char a; 

    a = -1; 

    if(a == -1) 
     printf("Yes\n"); 
    else 
     printf("No\n"); 

    return 0; 
} 

代碼a = -1分配一個實現定義值a;在大多數機器上,a將是255.測試a == -1unsigned charint進行比較,因此通常的促銷規則適用;因此,它被解釋爲

`(int)a == -1` 

由於a是255,(int)a仍然是255,並且測試產生false。

+0

「代碼a = -1」對不對? – user209347

+0

@ user209347修好了,謝謝。 – jch

+0

「實現定義的值」在所有符合的實現中,這將是「UCHAR_MAX」。 –

-1

我認爲這個問題最好由一個簡單的例子回答(警告:C++,但見解釋我的推理):

char c = -1; 
unsigned char u = -1; 
signed char s = -1; 
if (c == u) 
     printf("c == u\n"); 
if (s == u) 
     printf("s == u\n"); 
if (s == c) 
     printf("s == c\n"); 
if (static_cast<unsigned char>(s) == u) 
     printf("(unsigned char)s == u\n"); 
if (c == static_cast<char>(u)) 
     printf("c == (char)u\n"); 

輸出:

s == c 
(unsigned char)s == u 
c == (char)u 

C的治療價值在原樣使用時是不同的,但是您在該演員中正確地重新解釋這些位。我在這裏使用C++ static_cast來表明編譯器可以執行此類轉換。在C中,你只需要在括號中加前綴即可。沒有編譯器檢查以確保鑄造是在C.

+1

這是一個C問題。 C和C++是不同的語言。 – jch

+0

@jch:閱讀第一行說明在本例中查看使用C++的解釋。 – greg

+0

因此,如果我從「A == -1」這個問題中拿出我的例子,我必須明確地將其轉換爲「(signed char)A == -1」才能使其工作? – user209347

3
unsigned char A = -1; 

結果爲255.在賦值或初始化時沒有重新解釋。一個-1只是一堆1位的二進制補碼錶示,其中8個是逐字複製的。

比較有點不同,因爲文字-1int類型。

if (A == -1) 

會做促銷(隱式轉換)(int)A比較之前,所以你最終-1比較255。不等於。

是的,你必須小心與普通char

+2

「結果爲255」。那就是如果你的char是8位。不保證。 「8位機器,其中'sizeof(int)== sizeof(char)'」。 「int」至少爲16位。 –

+0

同意。我認爲char是8位。有沒有人見過不同的東西?編輯。 – SzG

+0

「有人見過不同的東西嗎?」可能的重複:http://stackoverflow.com/questions/2098149/what-platforms-have-something-other-than-8-bit-char –

4
unsigned char a = -1; 

ISO/IEC 9899:1999說,在6.3.1.3/2:

如果新類型是無符號的,所述值是通過反覆增加或減去 比最大值多一個轉換可在新的類型來表示,直到該值是新類型的範圍

我們添加(UCHAR_MAX+1)-1一次,結果是UCHAR_MAX,這顯然是範圍爲unsigned char

如果(A == -1)

還有很長的通道中6.3.1.8/1:

如果兩個操作數具有相同的類型,則不需要進一步的轉化。否則,如果兩個操作數具有有符號整數類型或兩者都具有無符號整數類型 ,則類型爲較小整數轉換等級的操作數爲 轉換爲具有較高等級的操作數的類型。

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

否則,如果用符號整型操作數的類型可以表示 所有與無符號整數類型的操作數的類型的值,則 與無符號整數類型的操作數被轉換到 的類型帶有符號整數類型的操作數。

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

unsigned char的排名小於int的排名。

如果int可以表示unsigned char能(其通常是這種情況),那麼兩個操作數都轉換爲int的所有值,並且比較返回false

如果int不能代表所有值unsigned char,它可以在罕見的機器發生與sizeof(int)==sizeof(char),那麼兩者都轉化爲unsigned int-1被轉換爲UINT_MAX這恰好是一樣UCHAR_MAX,並且比較返回true