2017-09-12 64 views
2

我只是執行以下代碼不同的數據類型 - 符號和無符號

main() 
{ 
    char a = 0xfb; 
    unsigned char b = 0xfb; 
    printf("a=%c,b=%c",a,b); 
    if(a==b) { 
    printf("\nSame"); 
    } 
    else { 
    printf("\nNot Same"); 
    } 
} 

對於這個代碼我得到的答案

A =? B =?

不同

爲什麼我沒有拿到一樣的,什麼是a和b的值?

+1

閱讀一本不錯的C書,瞭解不同數據類型的內存表示以及'signed'和'unsigned'數據類型之間的區別 – krpra

+3

「* Different *」的確是? – alk

+0

「a和b的值是多少」可以通過'printf(「a =%d,b =%d」,a,b)輕鬆調查;' – chux

回答

4

有兩個情況需要考慮:

  • 如果char類型默認無符號,既ab分配值251和程序將打印Same
  • 如果char類型默認,這是唉最常見的情況簽署,該定義char a = 0xfb;具有實現定義行爲0xfb251十進制)可能超出範圍爲char類型(通常-128127)。最有可能的值-5將被存儲到aa == b評估爲0因爲兩個參數在比較之前被提升爲int,因此-5 == 251將爲假。

printf("a=%c,b=%c", a, b);的行爲也依賴於系統的非ASCII字符-5251可能以意想不到的方式打印,如果在所有。但請注意,兩者的打印格式均與%c格式的打印格式相同,因此在打印前將參數轉換爲unsigned char。這將是更安全和更明確的嘗試printf("a=%d, b=%d\n", a, b);

使用gcc或clang,你可以嘗試用-funsigned-char來重新編譯你的程序,看看這個行爲會有什麼不同。

+0

最好的答案,因爲它解決'a = 0xfb;'具有實現定義的行爲。 – chux

6

if (a == b) ...在比較之前將字符提升爲整數,因此字符的符號性會影響發生的方式。無符號字符0xFB變成整數251;有符號字符0xFB變成整數-5。因此,他們是不平等的。

+0

在if之前, == b)',但在'char a = 0xfb;'時間。 – chux

+0

從某種意義上講,是的。單字節0xFB被正確解釋爲-5,即使存儲在一個字節中。這就是爲什麼在升級完成後,物理擴展爲0xFFFFFFFB,而另一個物理擴展爲0x000000FB。 –

+0

*這就是爲什麼促銷完成後,它實際上擴展到0xFFFFFFFB *也許,也許不是。行爲不取決於int的大小,也不取決於內存中整數的表示。將'0xfb'存儲到一個帶符號的8位'char'具有實現定義的行爲,在大多數當前的體系結構中將存儲'-5',其餘部分完全在所有體系結構中定義。 – chqrlie

0

char存儲從-128到127和unsigned char存儲從0到255 和0xfb表示251以十進制這超出了char a極限。

2

按照C標準(6.5.9平等運營商)

4如果兩個操作數的算術具有類型,通常的算術 轉換被執行 ....

通常的算術轉換包括整數提升。

來自C標準(6.3.1。1布爾值,字符,和整數)

2以下可以在表達式中使用的任何地方可使用int或 unsigned int類型: ...

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

因此,在這種平等表達

a == b 

的兩個操作數被轉換爲類型int。帶符號的操作數(假設char類型的行爲類型爲signed char)通過傳播符號位被轉換爲int類型。

作爲結果,由於二進制表示的差異,操作數具有不同的值。

如果char類型的行爲類型爲unsigned char(例如通過設置編譯器的相應選項),那麼顯然操作數將相等。

+0

*由於二進制表示的不同,導致操作數具有不同的值。*更確切地說,由於二進制表示的解釋存在差異。 – chqrlie

相關問題