2016-04-24 22 views
-2

我定義了一個名爲queryData的結構,如下面的代碼。當我嘗試使用shift和right操作來操作和分配一個數據qdata.data.data4 [0],將數據打印出來時,我之前陳述的數據是a char,它是8位,但當我打印它它實際上是32位,0xffffff8b。我不知道這是怎麼回事。謝謝。使用shift-right,出現錯誤

int main(void){ 
    union Data{ 
     char data2[2]; 
     char data4[4]; 
    }; 
    struct queryData{ 
     char byte; // 2bytes or 4bytes. 
     union Data data; 
    }; 
    struct queryData qdata; 
    unsigned long int data; 
    data = rand()%4294967295; 
    qdata.byte = 4; 
    qdata.data.data4[0] = (char)(data>>24); 
    qdata.data.data4[1] = (char)((data<<8)>>24); 
    qdata.data.data4[2] = (char)((data<<16)>>24); 
    qdata.data.data4[3] = (char)((data<<24)>>24); 
    printf("%ld\n",data); 
    printf("%x\n",qdata.data.data4[0]); 
    printf("%x\n",qdata.data.data4[1]); 
    printf("%x\n",qdata.data.data4[2]); 
    printf("%x\n",qdata.data.data4[3]); 
    printf("%x",(unsigned int)(1804289383<<8)>>24); 
    return EXIT_SUCCESS; 
} 

結果如下: The result after run

+1

右移符號值是實現定義。左移可以調用未定義的行爲。使用無符號的固定寬度類型! – Olaf

+4

哦,**不發佈文字鏈接或圖像** – Olaf

+0

[簽名右移=奇怪結果?](http://stackoverflow.com/q/3763263/995714)。不要使用像4294967295這樣的魔術數字,請使用'0xFFFFFFFF'或'〜0u'代替 –

回答

1

您使用了錯誤printf格式。對於char,使用%hhd作爲數字值。如果您希望以十六進制打印它,則必須使用unsigned char作爲類型,而不是char

你正在觀察的是你的char被提升爲int,並傳遞給printf。然後以十六進制形式打印該int作爲unsigned。因爲您的平臺似乎有簽名的char類型,並且對於負值使用二進制補碼,所以您會看到所有起始位都已打開的模式。

+0

明白了。謝謝〜 – user6132353

0

可變參數函數如printf會將小於int的所有整數提升爲int。由於char是一個整數(在你的情況下是8位有符號整數),所以你的字符通過符號擴展被提升爲int。由於8b具有領先的1位(並且作爲8位整數爲負數),所以它們正在被符號擴展,而樣本中的其他人則不會。

爲了避免這樣的促銷,你必須使用長度說明printf中:

printf("%hhx\n",qdata.data.data4[1]); 
+0

得到了。謝謝〜 – user6132353