2011-12-09 28 views
8

Vì vậy, tôi là một chút của một newbie để C và tôi tò mò để tìm ra lý do tại sao tôi nhận được hành vi bất thường này.Tại sao C in các giá trị hex của tôi không chính xác?

Tôi đang đọc một tệp 16 bit tại một thời điểm và chỉ in chúng ra như sau.

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

Các kết quả tìm kiếm một cái gì đó như thế này:

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

bất cứ ai có thể giải thích cho tôi tại sao dòng cuối cùng trong mỗi khối không in giá trị giống như thứ hai?

Trả lời

10

Điều này là do quảng bá loại số nguyên.

shorts của bạn đang được quảng bá hoàn toàn đến int. (đó là 32-bit ở đây) Vì vậy, đây là những khuyến mãi đăng ký mở rộng trong trường hợp này.

Do đó, printf() của bạn đang in ra các chữ số thập lục phân của toàn bộ 32 bit int.

Khi giá trị short của bạn là số âm, tiện ích mở rộng ký hiệu sẽ điền vào 16 bit hàng đầu với số tiền, do đó bạn nhận được ffffcade thay vì cade.


Lý do tại sao dòng này:

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

dường như làm việc là vì macro của bạn là mặc nhiên được thoát khỏi phía trên 16-bit.

2

Bạn đã khai báo rõ ràng hex làm giá trị đã ký (để làm cho nó không được ký unsigned short hex) sao cho bất kỳ giá trị nào trên 0x8FFF được coi là âm. Khi printf hiển thị nó như là một giá trị 322 bit int, nó sẽ được mở rộng bằng ký tự, gây ra số Fs hàng đầu. Khi bạn in giá trị trả lại của endian trước khi cắt bớt nó bằng cách gán nó cho hex toàn bộ 32 bit có sẵn và được in chính xác.

Các vấn đề liên quan