C++ 如何简单地以小端格式从缓冲区重建数字

C++ 如何简单地以小端格式从缓冲区重建数字,c++,C++,假设我有: typedef unsigned long long uint64; unsigned char data[BUF_SIZE]; uint64 MyPacket::GetCRC() { return (uint64)(data[45] | data[46] << 8 | data[47] << 16 | data[48] << 24 | (uint64)data[49] << 32|

假设我有:

typedef unsigned long long uint64;

unsigned char data[BUF_SIZE];    

uint64 MyPacket::GetCRC()
{
  return (uint64)(data[45] | data[46] << 8 | 
         data[47] << 16 | data[48] << 24 |
         (uint64)data[49] << 32| (uint64)data[50] << 40 |
         (uint64)data[51] << 48| (uint64)data[52] << 56);
}
typedef无符号长uint64;
无符号字符数据[BUF_大小];
uint64 MyPacket::GetCRC()
{

return(uint64)(data[45]| data[46]使用移位或顺序的最大优点是,无论您的主机是big-endian还是little-endian,它都可以工作


当然,您总是会调整表达式。就个人而言,我尝试加入“pairs”,即一次两个字节,然后是两个短字节,最后是两个长字节,因为这将帮助编译器生成更好的代码。

老实说,您的代码没有多大问题。它可以工作,而且速度很快。 我要改变的是,为了便于阅读,将其格式设置得更好一些:

uint64 MyPacket::GetCRC()
{
  return (uint64) data[45]       | 
         (uint64) data[46] << 8  | 
         (uint64) data[47] << 16 | 
         (uint64) data[48] << 24 |
         (uint64) data[49] << 32 | 
         (uint64) data[50] << 40 |
         (uint64) data[51] << 48 | 
         (uint64) data[52] << 56;
}
uint64 MyPacket::GetCRC()
{
返回(uint64)数据[45]|

(uint64)数据[46]好吧,也许更好的办法是交换顺序+强制转换

typedef unsigned long long uint64;

unsigned char data[BUF_SIZE];    

uint64 MyPacket::GetCRC()
{
  uint64 retval;
  unsigned char *rdata = reinterpret_cast<unsigned char*>(&retval);
  for(unsigned i = 0; i < 8; ++i) rdata[i] = data[52-i];
  return retval;
}
typedef无符号长uint64;
无符号字符数据[BUF_大小];
uint64 MyPacket::GetCRC()
{
uint64检索;
unsigned char*rdata=reinterpret_cast(&retval);
对于(无符号i=0;i<8;++i)rdata[i]=data[52-i];
返回返回;
}

这是我自己的一个类似于@x13n提供的

uint64 MyPacket::GetCRC()
{
    int offset=45;
    uint64 crc;
    memcpy(&crc, data+offset, 8);
    //std::reverse((char*)&crc, (char*)&crc + 8); // if this was a big endian machine
    return crc;
}

这将总是在一台小小的endian机器上运行。这里有一些很好的建议。啊..你现在已经定义了
数据
。谢谢。所以你不需要在移动数据[46]、[47]和[48]之前对uint64进行强制转换吗?似乎不需要。但为了完整性,我可能要补充一点抱歉-我的错误,移位操作符会自动升级:在“int”为16位,必须为数据(47)和数据[48 ]添加一个至少32位的类型,所以您是部分正确的@ GrHAMS。我在这里进行猜测,但是我认为C++中的移位操作应该在逻辑上相同,而不考虑“接口”。"。因此,您似乎在做的是将CRC的MSByte作为计算值中的LSB。这是您的意图吗?此代码假定它应该在大端机上执行,在小端机环境中执行时会产生错误的结果。是的,您是……我不需要反转看起来在或者小端硬件。所以52-i应该是45+i。如果不需要反转,单独转换就足够了:
return*reinterpret\u cast(&data[45])
。无论您是如何编写的,您都需要反转字节以获得正确的值。感谢您的提示…看起来它已经相当理想了。我更喜欢您的格式样式而不是我的格式样式。
uint64 MyPacket::GetCRC()
{
    int offset=45;
    uint64 crc;
    memcpy(&crc, data+offset, 8);
    //std::reverse((char*)&crc, (char*)&crc + 8); // if this was a big endian machine
    return crc;
}