首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >字节数组转换为C++中的整型

问字节数组转换为C++中的整型
EN

Stack Overflow用户
提问于 2011-07-28 14:56:02
回答 4查看 10.4K关注 0票数 6

下面是从字节数组中获取int16 (短)值的最有效的方法吗?

代码语言:javascript
复制
inline __int16* ReadINT16(unsigned char* ByteArray,__int32 Offset){
    return (__int16*)&ByteArray[Offset];
};

如果字节数组包含与机器具有相同字节顺序格式的字节转储,则将调用此代码。我们欢迎其他的选择。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-07-28 14:59:20

只有在你能保证Offset是偶数的情况下,你才应该使用这种方法。

代码语言:javascript
复制
inline int16_t ReadINT16(uint8_t *ByteArray, int32_t Offset){
    assert((Offset & 1) == 0); // Offset must be multiple of 2
    return *(int16_t*)&ByteArray[Offset];
};

还要注意的是,我稍微修改了一下,让它直接返回一个16位的值,因为返回一个指针,然后取消引用它,很可能比直接返回一个16位的值要“高效”得多。我还切换到了用于整数的标准Posix类型-我建议您也这样做。

票数 9
EN

Stack Overflow用户

发布于 2011-07-28 15:33:20

令我惊讶的是,还没有人提出这样的解决方案,既是对齐安全,又是跨所有架构的正确。(好吧,任何一个字节有8位的体系结构)。

代码语言:javascript
复制
inline int16_t ReadINT16(uint8_t *ByteArray, int32_t Offset)
{
    int16_t result;
    memcpy(&result, ByteArray+Offset, sizeof(int16_t));
    return result;
};

我认为memcpy的开销是可以避免的:

代码语言:javascript
复制
inline int16_t ReadINT16(uint8_t *ByteArray, int32_t Offset)
{
    int16_t result;
    uint8_t* ptr1=(uint8_t*)&result;
    uint8_t* ptr2 = ptr1+1;
    *ptr1 = *ByteArray;
    *ptr2 = *(ByteArray+1);
    return result;
};

我相信对齐问题不会在x86上产生异常。我还记得,当你遇到对齐问题时,SunOS上的Sparc就会彻底崩溃。

票数 4
EN

Stack Overflow用户

发布于 2011-07-28 15:14:38

代码语言:javascript
复制
inline __int16* ReadINT16(unsigned char* ByteArray,__int32 Offset)
{     
    return (__int16*)&ByteArray[Offset]; 
}; 

不幸的是,这在C++中有未定义的行为,因为您使用两种不同的类型访问存储,这在严格的别名规则下是不允许的。您可以使用char*访问类型的存储,但反之亦然。

根据我之前提出的问题,真正安全的方法是使用memcpy将字节复制到int中,然后使用它。(它很可能会被优化为您希望的相同代码,因此看起来效率非常低)。

你的代码可能会工作,大多数人似乎都会这样做……但重点是,当有一天编译器供应商生成的代码不是你希望的那样时,你不能哭着去找编译器供应商。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6855115

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档