编写反序列化函数以将字节数组转换为32位无符号整数的最佳方法是什么?
typedef unsigned long uint32;
uint32 deserialize_uint32(unsigned char *buffer)
{
uint32 value = 0;
value |= buffer[0] << 24;
value |= buffer[1] << 16;
value |= buffer[2] << 8;
value |= buffer[3];
return value;
}
unsigned char* deserialize_uint32B(unsigned char *buffer, uint32* value)
{
*value = 0;
*value |= buffer[0] << 24;
*value |= buffer[1] << 16;
*value |= buffer[2] << 8;
*value |= buffer[3];
return buffer + 4;
}
谢谢!或者如果有更好的方法请告诉我..谢谢!
答案 0 :(得分:2)
我更喜欢你的第一个变体而不是第二个。或者,您可以通过使用四个局部变量来利用并行处理,这些变量将各个字节移位正确的量。然后,在最后一行中return b0shifted | b1shifted | b2shifted | b3shifted
。
无论如何,这完全取决于你的编译器。您的第二个变体包含更多的加载/存储操作,因此第一个变体具有较少的抽象操作。
关于可读性,可理解性和清晰度,您的第一个变体很棒。它也适用于您正在使用的任何奇怪的平台(endianess,alignment),前提是CHAR_BIT == 8
。
答案 1 :(得分:1)
人们可以明智地使用铸造来轻松完成这项工作。只需将char缓冲区转换为您想要的类型。
uint32 deserialize_uint32(unsigned char *buf)
{
uint32 *x = (uint32*)buf;
return *x;
}
unsigned char * deserialize_uint32B(unsigned char *buffer, uint32* value)
{
*(uint32*)buffer = *value;
return buffer;
}
答案 2 :(得分:0)
你可以写:
#include <arpa/inet.h>
uint32_t deserialize_uint32(unsigned char *buffer) {
uint32_t res = *((uint32_t *) buffer);
return ntohl(res);
}
unsigned char *serialize_uint32(unsigned char *buffer, uint32_t *value) {
*((uint32_t *) buffer) = htonl(*value);
return buffer;
}
此实现确保字节顺序与底层架构无关。
答案 3 :(得分:0)
您的第一个方法可能会产生更好的代码,因为在第二个方法中,编译器必须假设指针data
和value
可以别名(尽管如果编译器能够内联,这可以减轻使用它的功能。)
如果您有C99编译器,您可能希望使用uint32_t
,inline
和第二个版本restrict
的优势。