uint_8、uint_16 和 uint_32 的用法

Usage of uint_8, uint_16 and uint_32

请详细解释每个案例,幕后发生了什么,以及为什么我会得到 55551 和 -520103681。

typedef uint_8 BYTE;        

BYTE arr[512];
fread(arr, 512, 1, infile);
printf("%i", arr[0]);

输出:255

typedef uint_16 BYTE;        

BYTE arr[512];
fread(arr, 512, 1, infile);
printf("%i", arr[0]);

输出:55551

typedef uint_32 BYTE;        

BYTE arr[512];
fread(arr, 512, 1, infile);
printf("%i", arr[0]);

输出:-520103681

我正在读取前四个字节为 255 216 255 244 的文件。

在你的3种情况下,在printf语句之前,arr数组的前4个字节(十六进制格式)为:FF D8 FF E0,对应255 216 255 224.

以下是对每个案例的解释:

  1. arr[0]有uint8_t类型,所以它的1字节值为0xFF,所以printf("%i", arr[0]);打印255,对应有符号十进制整数格式的0xFF %i 要求,整数大小为 4 个字节。

  2. arr[0] 有 uint16_t 类型,所以它的 2 字节值是 0xFFD8,所以 printf("%i", arr[0]); 打印 55551,对应有符号十进制整数格式的 0xFFD8 %i 要求,整数大小为 4 个字节。请注意,0xFFD8 被解释为小端(字节 0xD8 是 MSB)。

  3. arr[0]有uint32_t类型,所以它的4字节值为0xFFD8FFE0,所以printf("%i", arr[0]);打印-520103681,对应[=33中的0xFFD8FFE0 =]signed %i 要求的十进制整数格式,整数大小为 4 个字节。请注意,0xFFD8FFE0 被解释为小端(字节 0xE0 是 MSB)。

注意:我自愿将“255 216 255 244”从您的 post 更改为“255 216 255 224”。我想你打错了。

你好像误会了很多。您的示例中四分之三的行是有问题的。所以让我们剖析它们。

typedef uint_8 BYTE; 你为什么有这个 typedef 以及 uint_8 来自哪里 我建议你只使用 stdint.h 中的 uint8_t 并且对于一个最小的例子你可以跳过你的 typedef 完全字节。

documentation of fread 告诉我们:

  • 第二个参数是每个要读取的元素的大小
  • 第三个参数为要读取的元素个数

还有其他方法可以将值存入内存并通过复制和粘贴使程序可重现,我们只需将相应的值存入内存即可。如果您对恐惧有疑问,那就另当别论了。

所以它会是这些行之一(你的最后一个值必须是 224 而不是 244 才能得到 -520103681)

uint8_t arr[512] ={0xFF, 0xD8, 0xFF, 0xE0}; //{255, 216, 255, 224}
uint16_t arr[512] = {0xD8FF, 0xF4FF };//{255<<8 + 216, 255<<8 + 224} reversed because of the endianess
uint32_t arr[512] = {0xE0FFD8FF}; //{255<<24 + 216<<16 + 255<<8 + 224}

现在你可以看到数组的大小不同,16/32 位几乎不符合 BYTE

最后一行你用的printf()错了。如果您查找 printf() 的输出和长度说明符,您可以看到 i 用于 int(可能是 32 位)。

基本上你告诉它读取 arr[0](任何类型)作为有符号整数。 这会产生您在上面看到的值。 (几乎)正确的说明符是 %hhu for unsigned char%hu for unsigned short%u for unsigned int.

但是当您使用大小定义变量时,最好使用 inttypes.h 和说明符 :

PRIu8, PRIu16 and PRIu32 照这样

printf("%"PRIu8,arr[0]);

将它们放在一起产生:

#include  <stdio.h>
#include <inttypes.h>

int main(void)
{
  uint32_t arr[512] = {0xE0FFD8FF};
  printf("%"PRIu32,arr[0]);
  return 0;
}

如果您消除了代码中的所有问题,我们就离问题更近了。 问题 1 可能是您忘记了字节顺序,所以您可能期望字节的顺序不同。

此外,如果您对 printf 使用带符号的说明符并且 MSB 为 1,您将得到一个负值,如果您对无符号值使用正确的说明符,则不会发生这种情况。