[英]C language printf function and output problem
我需要幫助解決這個問題,所以如果有人遇到類似的問題,它會對我有很大幫助。
signed char c=0x10;
printf("%x", c<<0x4|c>>0x4);
為什么輸出是101?
在帶有移位運算符的表達式中,整數提升應用於每個操作數,在這種特殊情況下應用於對象c
。
來自 C 標准(6.5.7 位移位運算符)
3 對每個操作數執行整數提升。 結果的類型是提升的左操作數的類型....
因此,在整數提升之后,它將表示為(前提是sizeof( int )
等於4
)
00000010
這個表情
c<<0x4
產生以下值
00000100
而這個表達
c>>0x4
產生以下值
00000001
按位運算符 | 產量
00000100
|
00000001
========
00000101
結果不帶前導零輸出為
101
也就是說,函數 printf 將 int 類型的結果值輸出為 unsigned int 類型的對象,因為結果值可以用 unsigned int 類型的對象表示。
例如,要獲得預期的結果,請使用長度修飾符hh
printf("%#hhx", c<<0x4|c>>0x4);
在這種情況下,程序輸出將是
0x1
signed char c=0x10;
printf("%x", c<<0x4|c>>0x4);
為什么輸出是101?
因為c<<4==0x100
和c>>4==0x01
。 將它們組合在一起的結果是0x101
重要的是,在應用<<
運算符之前,對int
進行了隱式類型提升。
如果您希望交換半字節,則需要添加一些掩碼:
(c&0x0F)<<4 | (c&0xF0)>>4
在大多數表達式中,有signed char
會自動提升為int
,它至少為 16 位。 所以c<<0x4
用至少 16 位數據進行評估; 它不會像結果限制為 8 位那樣丟失高位。
所以c << 0x4
將 0001 0000 移位四位,產生 0001 0000 0000。而c >> 0x4
當然產生 0001。將它們組合在一起產生 0001 0000 0001,即 101 16 。
您可以通過各種方式去除高位。 一種是將子表達式顯式轉換為所需類型: (signed char) (c << 0x4) | c >> 0x4
(signed char) (c << 0x4) | c >> 0x4
。 請注意,這存在一個問題,即超出范圍的值到有符號類型的轉換是實現定義的。 以這種方式處理位時,通常最好使用無符號類型,因為這樣結果由 C 標准完全定義。
另一種方法是使用帶有“掩碼”的 AND 來選擇所需的位: (c << 0x4 | c >> 0x4) & 0xFF
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.