2

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

代码:

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

虽然我希望 val 包含0xFFFF它实际上包含0x00FF. 我究竟做错了什么?

4

4 回答 4

7

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

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

为了可靠地获得结果,您最好进行换档和或:

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

或者:

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

请注意,这明确提供了数据的大端(第一个选项)或小端(第二个)解释。

还要注意谨慎使用<<and |; 如果使用+代替|,则必须将移位表达式括起来或使用乘法代替移位:

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

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

于 2012-04-18T13:40:33.003 回答
6

好吧,unsigned char*当您应该取消引用 a 时,您正在取消引用short*

我认为这应该有效:

 short val = *((short*)(Temp+1))
于 2012-04-18T13:37:06.217 回答
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)依赖于字节序的事情可能是一个更好的主意

于 2012-04-18T13:37:26.407 回答
1

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

考虑以下定义Temp

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

根据系统的字节顺序,您将得到不同的结果转换Temp + 1为 a short *; 在小端系统上,结果将是值0x88FF,但在大端系统上,结果将是0xFF88

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

你可以使用的是:

short val = (((short)Temp[1]) << 8) | Temp[2];
于 2012-04-18T13:43:00.050 回答