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.
以下是对每个案例的解释:
arr[0]
有uint8_t类型,所以它的1字节值为0xFF,所以printf("%i", arr[0]);
打印255,对应有符号十进制整数格式的0xFF %i
要求,整数大小为 4 个字节。
arr[0]
有 uint16_t 类型,所以它的 2 字节值是 0xFFD8,所以 printf("%i", arr[0]);
打印 55551,对应有符号十进制整数格式的 0xFFD8 %i
要求,整数大小为 4 个字节。请注意,0xFFD8 被解释为小端(字节 0xD8 是 MSB)。
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,您将得到一个负值,如果您对无符号值使用正确的说明符,则不会发生这种情况。
请详细解释每个案例,幕后发生了什么,以及为什么我会得到 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.
以下是对每个案例的解释:
arr[0]
有uint8_t类型,所以它的1字节值为0xFF,所以printf("%i", arr[0]);
打印255,对应有符号十进制整数格式的0xFF%i
要求,整数大小为 4 个字节。arr[0]
有 uint16_t 类型,所以它的 2 字节值是 0xFFD8,所以printf("%i", arr[0]);
打印 55551,对应有符号十进制整数格式的 0xFFD8%i
要求,整数大小为 4 个字节。请注意,0xFFD8 被解释为小端(字节 0xD8 是 MSB)。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,您将得到一个负值,如果您对无符号值使用正确的说明符,则不会发生这种情况。