2011-12-09 3 views
8

私はCの初心者ですが、なぜこのような異常な動作をしているのか不思議です。Cが16進数値を正しく表示しないのはなぜですか?

私は一度に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の16進数を出力しています。

shortの値が負の場合、符号拡張によって上位16ビットが1で埋められるため、cadeではなくffffcadeになります。


この行理由:あなたのマクロは暗黙のうち上位16ビットを取り除くされているので

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

が動作しているようです。

2

0x8FFFを超える値が負であるとみなされるように、hexを符号付きの値(暗黙の書き込みの場合はunsigned short hex)に暗黙的に宣言しています。 printfが32ビットのintの値として表示すると、1で符号拡張され、先頭にFsが表示されます。 endianの戻り値を切り捨てる前に、hexに割り当てると、32ビットが使用可能になり、正しく印刷されます。

関連する問題