在C中将char数组转换为int

时间:2013-10-05 11:25:24

标签: c

这是将数组转换为数字的安全方法吗?

// 23 FD 15 94 -> 603788692
char number[4] = {0x94, 0x15, 0xFD, 0x23};
uint32_t* n = (uint32_t*)number;
printf("number is %lu", *n);

更多信息

我在具有LSB架构的嵌入式设备中使用它,不需要是可移植的。 我目前正在使用移位,但如果这段代码是安全的,我更喜欢它。

3 个答案:

答案 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数组。