为什么C打印我的hex值不正确?

所以我对C来说是一个新手,我很想知道为什么我会得到这种不寻常的行为。

我一次读取16位文件,然后按如下方式打印出来。

#include  #define endian(hex) (((hex & 0x00ff) <> 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 

任何人都可以向我解释为什么每个块中的最后一行不会打印与第二行相同的值?

这是由于整数类型提升。

你的shorts被隐含地提升为int 。 (这里是32位)所以这些是在这种情况下的符号扩展促销。

因此, printf()将打印出完整32位int的hex数字。

当您的short值为负时,符号扩展将使用1填充前16位,因此您获得ffffcade而不是ffffcade


这条线的原因:

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

似乎工作是因为你的宏隐含地摆脱了高16位。

格式字符串中的占位符%x将相应的参数解释为unsigned int

要将参数打印为short ,请将长度修饰符h添加到占位符:

 printf("%hx", hex); 

http://en.wikipedia.org/wiki/Printf_format_string#Format_placeholders

您已隐式声明hex为有符号值(使其无符号写入unsigned short hex ),以便超过0x8FFF任何值0x8FFF被视为负数。 当printf将其显示为32位int值时,它会用1进行符号扩展,从而导致前导Fs 。 在通过将其分配为hex来截断它之前打印endian的返回值时,可以使用完整的32位并正确打印。