如何将字符数组转换为不对齐位置的 int

How to cast char array to int at non-aligned position?

本文关键字:对齐 位置 int 转换 字符 数组      更新时间:2023-10-16
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 charunsigned char

最好的办法是使用按位移位运算符(>><<)和逻辑|&char值吸收到int中。此外,请考虑使用 int32_t 构建到 16 位或 64 位 int 的目标。

没有办法,将指针转换为错误对齐的指针是未定义的。

您可以使用memcpychar数组复制到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];