2015-09-30 135 views
-1

我想知道爲什麼printf語句在下面的代碼中將字符值顯示爲4字節值(fffffffe)。由於字符是1字節,所以我認爲我們應該只得到FE一個字節值的結果。打印反轉字符

int main(void) 
{ 
    unsigned char a4=1; 
    char b4=1; 
    printf("inverted a4 = %x\t b4= %x\n",~a4, ~b4); 
    return(0); 
} 
+1

打印用'hh'如在'的printf( 「倒A4 =%HHX \噸B4 =%HHX \ n」 個,〜 a4,〜b4);'以避免打印符號擴展名。 – chux

回答

2

當你做任何算術或位操作char量,它被悄悄地轉換爲int第一。這被稱爲integer promotion。它也會影響short(和signed char,unsigned charunsigned short)。 (從技術上講,如果sizeof(unsigned short) == sizeof(unsigned int)然後unsigned short將促進unsigned int而非int,但你可能不會在與特性的系統跳閘了,儘管它仍然C標準允許的。)

發生在charshort當它們通過匿名參數傳遞到printf(或任何其他可變參數函數)。

所以,你的代碼

unsigned char a4=1; 
char b4=1; 
printf("inverted a4 = %x\t b4= %x\n",~a4, ~b4); 

相當於

... 
printf("inverted a4 = %x\t b4= %x\n", (int) ~(int)a4, (int) ~(int)b4); 

(該在~投後沒有做任何事情,但我已經寫它無論如何強調的是,轉換可能發生,因爲算術和因爲參數傳遞。)

有沒有辦法來打開這種行爲關閉。爲了得到你想要的效果,我會寫

static_assert(CHAR_BIT == 8); 
printf("inverted a4 = %02x\tb4 = %02x\n", 
     (~(unsigned int)a4) & 0xFFu, 
     (~(unsigned int)b4) & 0xFFu); 

這和MikeCAT和尼克建議的代碼之間的區別是,所有的位操作上無符號量完成。有些操作在應用於帶符號數量時具有未定義的行爲,並且我無法準確記住規則是什麼,所以我只是避免將它們中的任何一個用於有符號數量。 (從%x%02x的變化僅僅是爲了美觀。)

static_assert失敗的系統現在很少見,但仍然被C標準允許。我主要把它包括在內以記錄程序的期望。 (該0xFFu掩模和%02x格式化是錯具有用於CHAR_BIT不同的值的系統。)

0

sizeof(~b4)爲4中Wandbox

要得到只有FE,使用AND掩碼。
此外,將%x更改爲%X以獲得FE,而不是fe。

#include <stdio.h> 

int main(void) 
{ 
    unsigned char a4=1; 
    char b4=1; 
    printf("inverted a4 = %X\t b4= %X\n",(~a4) & 0xFF, (~b4) & 0xFF); 
    return(0); 
} 
0

參數%X和%x預計爲int

您提供char,它被鑄造爲int

的解決方案是爲MikeCAT給:

printf("inverted a4 = %X\t b4= %X\n",(~a4) & 0xFF, (~b4) & 0xFF); 
0

這樣做的原因是這樣的......(省略號)函數C.工作當char參數提供給省略的功能,它是「擴大'int(或unsigned int,取決於char是有符號還是無符號)。實際上,小於int的所有東西都被擴展(正確的術語被提升)爲int。作爲這次升級的結果,當printf看到這個價值時,它已經被提升了。順便提一下,float以同樣的方式被提升爲double。

0

編譯器在將字符反轉之前將字符(0x01)提升爲32位整數(0x00000001),這會給出值(0xFFFFFFFE)。

你可以做一個位與作爲其他的答案中提到,或添加一個類型轉換的答案轉換回char類型之後:

unsigned char a4=1; 
char b4=1; 
printf("inverted a4 = %X\t b4= %X\n",(unsigned char)(~a4), (char)(~b4)); 
return(0); 
+0

'(char)' - >'(unsigned char)' – BLUEPIXY

+0

它不給出'0xFFFFFFFE'的值;它給出值'-2'。 –

2

~操作者的操作經歷整數促銷charunsigned char類型的操作數被提升爲int,結果爲int

char b4=1; 

b4char類型。

~b4 

b4值晉升爲int,並且操作者~產生的1按位求補。如果int是32位,則結果是-2,假設有符號整數的2的補碼錶示。

printf"%x\n", ~b4); 

int-2被打印,好像它是unsigned char類型;結果是fffffffe

如果你只想低8位,你可以使用一個位掩碼:

printf("%X\n", ~b4 & 0xFF); 

這將打印FE