在C / C ++中是否有办法在任何位置将char数组转换为int?
我尝试了以下内容,如果我尝试使用非const偏移的指针算法,它会自动对齐到最接近的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
更新
目前我的主要问题是:为什么d1值正确但d2不正确?这对其他编译器也是如此吗?这种行为可以改变吗?
答案 0 :(得分:4)
不,你不能以便携的方式做到这一点。
尝试从char*
转换为int*
时遇到的行为在C和C ++中都是未定义(可能是因为您发现的原因: int
可能在4字节边界上对齐,data
当然是连续的。)
(data+3
有效但data+p
不起作用的事实可能是由于编译时间与运行时评估有关。)
另请注意,{C}或C ++中未指定char
的签名,因此如果您正在编写此类代码,则应使用signed char
或unsigned char
。
最好的办法是使用按位移位运算符(>>
和<<
)和逻辑|
以及&
将char
值吸收到{{} 1}}。如果您使用16位或64位int
来构建目标,请考虑使用int32_t
。
答案 1 :(得分:2)
没有办法将指针转换为错误对齐的指针是未定义的。
您可以使用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];