如何将字符数组转换为不对齐位置的 int
How to cast char array to int at non-aligned position?
C
/C++有没有办法在任何位置将字符数组转换为整数?
我尝试了以下方法,如果我尝试使用具有非常量偏移量的指针算术,它会自动对齐到最接近的 32 位(在 32 位架构上):
unsigned char data[8];
data[0] = 0; data[1] = 1; ... data[7] = 7;
int32_t p = 3;
int32_t d1 = *((int*)(data+3)); // = 0x03040506 CORRECT
int32_t d2 = *((int*)(data+p)); // = 0x00010203 WRONG
更新:
- 如评论中所述,输入以 3 元组的形式出现,我不能改变这一点。
- 我想将 3 个值转换为 int 以进一步处理和此转换应尽可能快。
- 这解决方案不必是跨平台的。我正在与一个非常特定的编译器和处理器,因此可以假设它是 32具有大端序的位架构。
- 结果的最低字节对我来说无关紧要(见上文)。
我目前的主要问题是:为什么 d1 有正确的值,而 d2 没有?其他编译器也是如此吗?这种行为可以改变吗?
不,你不能以可移植的方式做到这一点。
尝试从 char*
转换为 int*
时遇到的行为在 C 和 C++ 中都没有定义(可能是由于您发现的原因:int
可能在 4 字节边界上对齐,data
当然是连续的。
(data+3
有效但data+p
无效的事实可能是由于编译时间与运行时评估。
另请注意,char
的符号性未在 C 或 C++ 中指定,因此,如果要编写此类代码,则应使用 signed char
或 unsigned char
。
最好的办法是使用按位移位运算符(>>
和<<
)和逻辑|
和&
将char
值吸收到int
中。此外,请考虑使用 int32_t
构建到 16 位或 64 位 int
的目标。
没有办法,将指针转换为错误对齐的指针是未定义的。
您可以使用memcpy
将char
数组复制到int32_t
中。
int32_t d = 0;
memcpy(&d, data+3, 4); // assuming sizeof(int) is 4
大多数编译器都有内置函数,用于memcpy
具有恒定大小参数,因此这可能不会产生任何运行时开销。
即使像您显示的那样允许正确对齐的指针进行转换,取消引用此类指针也会违反严格锯齿。有效类型为 char[]
的对象不得通过 int
类型的左值进行访问。
通常,类型双关是依赖于字节序的,并且以与字节序无关的方式转换表示 RGB 颜色的 char
数组可能更容易完成,例如
int32_t d = (int32_t)data[2] << 16 | (int32_t)data[1] << 8 | data[0];
相关文章:
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 如何创建一个QTableWidgetItem,用长文本右对齐,左边有省略号
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 64位机器上的C++内存对齐
- 为什么我可以将变量存储在不是其最小对齐方式的倍数的地址?
- 使 std::vector 分配对齐内存的现代方法
- C++ cout 将双精度对齐到精度 2 并正确对齐
- 在 64 位边界上对齐C++结构数组?
- 使用 g++7 构建的代码在访问未对齐的内存时崩溃
- 在 capnp FlatArrayMessageReader 的对齐内存缓冲区中接收 zmq 消息
- 是否值得对齐变量?
- 初始化派生结构的基部分/意外打包派生结构字段以对齐基结构的间隙
- 对齐和对齐的实际用例C++关键字
- 如何减少代码的运行时间以对齐文本?
- 指向包含对齐 C 结构C++类的 C 指针的对齐问题
- 如何检查指针是否指向正确对齐的内存位置
- C++ 提升日志位置(索引)格式对齐
- C++ 将文本文件中不同行/位置的相同单词与每行中的相同位置对齐
- 将对象位置与网格对齐
- 对齐C++指针位置的目的是什么