从char数组中转换一个short

时间:2012-04-18 13:33:42

标签: c casting

我在这里遇到了一个小问题。我有一个unsigned char数组,我试图访问字节2-3(0xFF0xFF)并将其值作为简短值。

代码:

 unsigned char Temp[512] = {0x00,0xFF,0xFF,0x00};
 short val = (short)*((unsigned char*)Temp+1)

虽然我希望val包含0xFFFF,但它实际上包含0x00FF。我做错了什么?

4 个答案:

答案 0 :(得分:7)

当数据未正确对齐时,无法保证您可以访问short

在某些计算机上,特别是RISC计算机上,您会因未对齐访问而出现总线错误和核心转储。在其他机器上,未对齐的访问将涉及到内核的陷阱以修复错误 - 这比核心转储快一点。

为了可靠地获得结果,你最好做转移和/或:

val = *(Temp+1) << 8 | *(Temp+2);

或:

val = *(Temp+2) << 8 | *(Temp+1);

请注意,这明确提供了数据的big-endian(第一选项)或little-endian(第二)解释。

另请注意谨慎使用<<|;如果您使用+而不是|,则必须使用shift表达式括号或使用乘法而不是shift:

val = (*(Temp+1) << 8) + *(Temp+2);
val = *(Temp+1) * 256 + *(Temp+2);

合乎逻辑并使用逻辑或算术,而不是混合。

答案 1 :(得分:6)

当您应该解除unsigned char*

时,您取消引用short*

我认为这应该有效:

 short val = *((short*)(Temp+1))

答案 2 :(得分:4)

您的问题是您只访问数组的一个字节:

  • *((unsigned char*)Temp+1)会取消引用Temp+1的指针0xFF
  • (short)*((unsigned char*)Temp+1)会将取消引用的结果转换为short。将unsigned char 0xFF简化为简短显然会为您提供0x00FF

所以你要做的是*((short*)(Temp+1))

但是应该注意到你正在做的是一个可怕的黑客。首先,当你有不同的chars时,结果显然取决于机器的字节顺序。

其次,无法保证所访问的数据被正确对齐以便作为简短的访问。

因此,根据您的架构的字节顺序执行short val= *(Temp+1)<<8 | *(Temp+2)short val= *(Temp+2)<<8 | *(Temp+1)这样的操作可能更好一点

答案 3 :(得分:1)

我不推荐这种方法,因为它是特定于体系结构的。

考虑Temp的以下定义:

unsigned char Temp[512] = {0x00,0xFF,0x88,0x00};

根据系统的字节顺序,您会得到Temp + 1short *的不同结果;在一个小端系统上,结果将是值0x88FF,但在Big endian系统上,结果将是0xFF88

此外,我认为这是一个未定义的演员,因为对齐问题。

你可以使用的是:

short val = (((short)Temp[1]) << 8) | Temp[2];