为什么C不正确地打印我的十六进制值?

为什么C不正确地打印我的十六进制值?,c,C,所以我对C有点生疏,我很好奇为什么我会有这种不寻常的行为 我一次读取一个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;

所以我对C有点生疏,我很好奇为什么我会有这种不寻常的行为

我一次读取一个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);
     }   
   }
 }

有人能解释一下为什么每个块中的最后一行打印的值与第二行不同吗?

这是由于整型升级

您的
短片
正在隐式升级为
int
。(这里是32位)在这种情况下,这些是符号扩展促销

因此,您的
printf()
正在打印出完整32位
int
的十六进制数字

当您的
short
值为负值时,符号扩展将用1填充顶部16位,因此您得到
ffffffcade
而不是
cade


这一行的原因是:

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

似乎有效是因为宏隐式地去掉了上面的16位。

您隐式地将
十六进制
声明为有符号值(使其成为无符号写入
无符号短十六进制
),因此
0x8FFF
上的任何值都被视为负值。当printf将其显示为32位
int
值时,它会以1进行符号扩展,导致前导的
Fs
。在通过将
endian
分配给
hex
来截断它之前,当您打印
endian
的返回值时,完整的32位可用并正确打印。

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

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

printf("%hx", hex);

printf("%hx", hex);