2011-12-09 27 views
8

所以我對C有點新手,我很想弄清楚爲什麼我會得到這種不尋常的行爲。爲什麼C不正確地打印我的十六進制值?

我一次讀取一個文件16位,只是按如下方式打印出來。

#include <stdio.h> 

#define endian(hex) (((hex & 0x00ff) << 8) + ((hex & 0xff00) >> 8)) 

int main(int argc, char *argv[]) 
{ 
    const int SIZE = 2; 
    const int NMEMB = 1; 
    FILE *ifp; //input file pointe 
    FILE *ofp; // output file pointer 

    int i; 
    short hex; 
    for (i = 2; i < argc; i++) 
    { 
    // Reads the header and stores the bits 
    ifp = fopen(argv[i], "r"); 
    if (!ifp) return 1; 
    while (fread(&hex, SIZE, NMEMB, ifp)) 
    { 
     printf("\n%x", hex); 
     printf("\n%x", endian(hex)); // this prints what I expect 
     printf("\n%x", hex); 
     hex = endian(hex); 
     printf("\n%x", hex); 
    } 
    } 
} 

結果是這個樣子:

ffffdeca 
cade // expected 
ffffdeca 
ffffcade 
0 
0 // expected 
0 
0 
600 
6 // expected 
600 
6 

誰能向我解釋爲什麼最後線每塊不打印相同的值作爲第二?

回答

10

這是由於整數類型提升。

您的shorts正被隱式升級到int。 (這裏是32位)所以在這種情況下,這些是簽名擴展促銷。

因此,您的printf()正在打印出完整的32位int的十六進制數字。

當您的short值爲負數時,符號擴展名將填入前16位,因此您得到ffffcade而不是cade


之所以這樣一行:

printf("\n%x", endian(hex)); 

似乎工作是因爲你的宏隱含擺脫高16位。

2

您已隱式聲明hex作爲有符號值(使其無符號寫入unsigned short hex),以便超過0x8FFF的任何值都被認爲是負值。當printf將其顯示爲32位int值時,它會用1進行符號擴展,導致前導Fs。在將hex分配給hex截斷之前,打印endian的返回值時,將提供完整的32位並正確打印。

相關問題