这是将数组转换为数字的安全方法吗?
// 23 FD 15 94 -> 603788692
char number[4] = {0x94, 0x15, 0xFD, 0x23};
uint32_t* n = (uint32_t*)number;
printf("number is %lu", *n);
更多信息
我在具有LSB架构的嵌入式设备中使用它,不需要是可移植的。 我目前正在使用移位,但如果这段代码是安全的,我更喜欢它。
答案 0 :(得分:3)
不,这不安全。
这违反了C别名规则,即只能通过自己的类型,签名/无符号变体或字符类型访问对象。它还可以通过打破对齐来调用未定义的行为。
从数组中获取uint32_t
值的安全解决方案是在<<
值上使用按位运算符(&
和char
)来形成{{1 }}。
答案 1 :(得分:3)
没有。如果 是整数,则只允许以整数形式访问。
但是这里你可以通过简单地转换逻辑来操纵对象的二进制表示:
uint32_t n;
unsigned char * p = (unsigned char *)&n;
assert(sizeof n == 4); // assumes CHAR_BIT == 8
p[0] = 0x94; p[1] = 0x15; p[2] = 0xFD; p[3] = 0x23;
道德:您可以将每个对象视为一个字节序列,但您不能将任意字节序列视为任何特定对象。
此外,类型的二进制表示非常依赖于平台,因此无法确定从中获得的实际整数值。如果您只想从基数为256的数字合成一个整数值,请使用常规数学:
uint32_t n = 0x94 + (0x15 * 0x100) + (0xFD * 0x10000) + (0x23 * 0x1000000);
这完全独立于平台,并且纯粹根据值表达您想要的内容,而不是表示。将它留给编译器生成代码的机器表示。
答案 2 :(得分:0)
你最好用这样的东西(更便携):
int n = (c[3]<<24)|(c[2]<<16)|(c[1]<<8)|c[0];
其中c是 unsigned char数组。