我想知道爲什麼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);
}
我想知道爲什麼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);
}
當你做任何算術或位操作上char
量,它被悄悄地轉換爲int
第一。這被稱爲integer promotion。它也會影響short
(和signed char
,unsigned char
和unsigned short
)。 (從技術上講,如果sizeof(unsigned short) == sizeof(unsigned int)
然後unsigned short
將促進unsigned int
而非int
,但你可能不會在與特性的系統跳閘了,儘管它仍然C標準允許的。)
這也發生在char
和short
當它們通過匿名參數傳遞到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
不同的值的系統。)
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);
}
參數%X和%x預計爲int
。
您提供char
,它被鑄造爲int
。
的解決方案是爲MikeCAT給:
printf("inverted a4 = %X\t b4= %X\n",(~a4) & 0xFF, (~b4) & 0xFF);
這樣做的原因是這樣的......(省略號)函數C.工作當char參數提供給省略的功能,它是「擴大'int(或unsigned int,取決於char是有符號還是無符號)。實際上,小於int的所有東西都被擴展(正確的術語被提升)爲int。作爲這次升級的結果,當printf看到這個價值時,它已經被提升了。順便提一下,float以同樣的方式被提升爲double。
編譯器在將字符反轉之前將字符(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);
'(char)' - >'(unsigned char)' – BLUEPIXY
它不給出'0xFFFFFFFE'的值;它給出值'-2'。 –
的~
操作者的操作經歷整數促銷 。 char
或unsigned char
類型的操作數被提升爲int
,結果爲int
。
char b4=1;
b4
是char
類型。
~b4
的b4
值晉升爲int
,並且操作者~
產生的1
按位求補。如果int
是32位,則結果是-2
,假設有符號整數的2的補碼錶示。
printf"%x\n", ~b4);
的int
值-2
被打印,好像它是unsigned char
類型;結果是fffffffe
。
如果你只想低8位,你可以使用一個位掩碼:
printf("%X\n", ~b4 & 0xFF);
這將打印FE
。
打印用'hh'如在'的printf( 「倒A4 =%HHX \噸B4 =%HHX \ n」 個,〜 a4,〜b4);'以避免打印符號擴展名。 – chux