【发布时间】:2020-09-03 16:20:59
【问题描述】:
在这个项目中,我应该接收一个数据包,并将其中的一部分转换为一个无符号整数,并获得 Big-Endian 和 Little-Endian 结果。最初,我只想将字节数组(数据包)内的指针转换为无符号整数类型,该类型会自动将接收到的值放入 Big-Endian 形式,例如 (uint32_be_t*)packet;,类似于它自动放入 Little-Endian 的方式做(uint32_t*)packet时的形式。
由于找不到自动执行此操作的类型,因此我决定创建自己的结构,称为“u32”,它具有“get”方法,该方法以 Big-Endian 形式获取值,以及“get_le”它以 Little-Endian 形式获取值。但是,我注意到当我这样做时,我会从 Little-Endian 结果中得到一个否定的结果。
struct u32 {
u8 data[4] = {};
uint32_t get() {
return ((uint32_t)data[3] << 0)
| ((uint32_t)data[2] << 8)
| ((uint32_t)data[1] << 16)
| ((uint32_t)data[0] << 24);
}
uint32_t get_le() {
return ((uint32_t)data[3] << 24)
| ((uint32_t)data[2] << 16)
| ((uint32_t)data[1] << 8)
| ((uint32_t)data[0] << 0);
}
};
为了模拟一个数据包,我只是创建了一个字符数组,然后像这样将一个 u32* 转换为它:
int main() {
char ary[] = { 0x00, 0x00, 0x00, (char)0xF4 };
u32* v = (u32*)ary;
printf("%d %d\n", v->get(), v->get_le());
return 0;
}
然后我得到了结果:244 -201326592
为什么会这样? “get_le”的返回类型是 uint32_t,第一个函数“get”应该返回 Big-Endian 无符号整数,它执行正确。
顺便说一句,这只是一个突然出现在我脑海中的测试,所以我去图书馆在类之间测试它,但不幸的是,这意味着我必须使用在线编译器 (onlinegdb),但我认为它在 Visual Studio 中的工作方式相同。此外,如果您对如何改进我的代码有任何建议,我们将不胜感激。我正在使用 Visual Studio 2019,并且可以使用 cstdlib。
【问题讨论】:
-
char具有实现定义的签名。如果您不希望它可能将其解释为有符号值,请显式使用unsigned char。 -
您希望
%u用于无符号整数,%d用于有符号整数。 -
u8-> 为什么不uint8_t? -
你还用什么?我讨厌使用 cout 因为我必须在每个值之间放置一个
-
这就是为什么没人喜欢 printf了。这是一个略带双曲线的陈述。不是每个人都讨厌
printf()