2011-12-09 20 views
8

Więc jestem trochę początkujący dla C i jestem ciekawy, aby dowiedzieć się, dlaczego dostaję to niezwykłe zachowanie.Dlaczego C drukuje moje wartości szesnastkowe niepoprawnie?

Czytam plik 16 bitów na raz i po prostu je wypisuję w następujący sposób.

#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); 
    } 
    } 
} 

Wyniki wyglądać następująco:

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

Czy ktoś może mi wyjaśnić dlaczego ostatni linia w każdym bloku nie drukuje taką samą wartość jako drugi?

Odpowiedz

10

Jest to związane z całkowitą promocją typu.

Twoje shorts są niejawnie promowane na int. (co jest tutaj 32-bitowe) Tak więc są to promocje rozszerzania znaków w tym przypadku.

Dlatego Twoja printf() drukuje cyfry szesnastkowe z pełnym 32-bitowym int.

Gdy Twoja wartość short jest ujemna, rozszerzenie znaku wypełni 16 pierwszych bitów, więc otrzymasz ffffcade zamiast .


Powodem tej linii:

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

wydaje się działać tak, ponieważ makra jest niejawnie pozbycie górnych 16 bitów.

2

Użytkownik domyślnie oznaczył hex jako podpisaną wartość (w celu utworzenia niepodpisanego zapisu unsigned short hex), tak aby każda wartość przekraczająca 0x8FFF była uznawana za wartość ujemną. Gdy printf wyświetla ją jako 32-bitową wartość int, jest ona rozszerzona o znaki, powodując wiodącą Fs. Po wydrukowaniu wartości zwracanej endian przed obcięciem przez przypisanie jej do hex pełne 32 bity są dostępne i drukowane poprawnie.

Powiązane problemy