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을 사용하여 부호 확장되고 행이 이됩니다. 에 할당하여 자르기 전에 endian의 반환 값을 인쇄하면 전체 32 비트가 사용 가능하고 올바르게 인쇄됩니다.

관련 문제