我在这里遇到了一个小问题。我有一个 unsigned char 数组,我正在尝试访问字节 2-3 (0xFF
和0xFF
) 并将它们的值作为一个短值。
代码:
unsigned char Temp[512] = {0x00,0xFF,0xFF,0x00};
short val = (short)*((unsigned char*)Temp+1)
虽然我希望 val 包含0xFFFF
它实际上包含0x00FF
. 我究竟做错了什么?
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);
合乎逻辑,使用逻辑或算术,而不是混合使用。
好吧,unsigned char*
当您应该取消引用 a 时,您正在取消引用short*
我认为这应该有效:
short val = *((short*)(Temp+1))
您的问题是您只访问数组的一个字节:
*((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)
依赖于字节序的事情可能是一个更好的主意
我不推荐这种方法,因为它是特定于架构的。
考虑以下定义Temp
:
unsigned char Temp[512] = {0x00,0xFF,0x88,0x00};
根据系统的字节顺序,您将得到不同的结果转换Temp + 1
为 a short *
; 在小端系统上,结果将是值0x88FF
,但在大端系统上,结果将是0xFF88
。
另外,我认为这是一个未定义的演员阵容,因为对齐问题。
你可以使用的是:
short val = (((short)Temp[1]) << 8) | Temp[2];