将一个UINT16值转换为一个UINT8数组[2]

19

这个问题基本上是我其他问题的后半部分

如何将 UINT16 值转换为 UINT8 * 数组,避免使用循环并避免字节序问题。

基本上,我想做这样的事情:

UINT16 value = 0xAAFF;
UINT8 array[2] = value;

这样做的最终结果是将值存储到一个UINT8数组中,同时避免端序转换。
UINT8 * mArray;
memcpy(&mArray[someOffset],&array,2);

当我只是使用UINT16值进行memcpy时,它会转换为小端序,这会破坏输出结果。我试图避免使用大小端转换函数,但我认为我可能没有那么幸运。

6个回答

48

怎么样?

UINT16 value = 0xAAFF;
UINT8 array[2];
array[0]=value & 0xff;
array[1]=(value >> 8);

这应该会独立于字节顺序而产生相同的结果。

或者,如果你想使用数组初始化器:

UINT8 array[2]={ value & 0xff, value >> 8 };

然而,只有当value是常量时才有可能实现这一点。


8

不需要条件编译。您可以进行位移操作以获取值的高位和低位字节:

uint16_t value = 0xAAFF;
uint8_t hi_lo[] = { (uint8_t)(value >> 8), (uint8_t)value }; // { 0xAA, 0xFF }
uint8_t lo_hi[] = { (uint8_t)value, (uint8_t)(value >> 8) }; // { 0xFF, 0xAA }

角色是可选的。

3
问题标签是C ++,使用C ++转换。 - Fernando N.

7
假设你想让数组中高位字节在低位字节之上:
array[0] = value & 0xff;
array[1] = (value >> 8) & 0xff;

3
0xff掩码是不必要的:从16位转换为8位整数时会丢弃高字节(无符号转换是有定义的!) - Christoph
4
没错,但我通常会掩盖一切以增强可读性。有时候我甚至会进行0的位移操作,这样每一行看起来都整齐划一。任何优秀的编译器都会优化掉不必要的语句,因此这样做值得。 - Jonathan

1
union TwoBytes
{
    UINT16 u16;
    UINT8 u8[2];
};

TwoBytes Converter;
Converter.u16 = 65535;
UINT8 *array = Converter.u8;

2
这与字节序有关。 - Jonathan

0

我使用这个线程开发了一个可跨越多种数组大小的解决方案:

UINT32 value = 0xAAFF1188;
int size = 4;
UINT8 array[size];

int i;
for (i = 0; i < size; i++)
{
    array[i] = (value >> (8 * i)) & 0xff;
}

0
一个临时的转换为 UINT16* 应该可以做到:
((UINT16*)array)[0] = value;

1
这不起作用,因为它仍然对字节序敏感(基本上,它与问题中的memcpy执行相同的操作)。 - Martin B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接