2012-11-30 47 views
1

可能重复:
convert big endian to little endian in C [without using provided func]无符号整型成小尾形式

我无法与这一部分:如果我想采取一个32位的数字,我想将它的字节(1字节= 8位)从大端移到小端形式。例如:

可以说我有数字1

在32位,这是它会是什么样子:

1st byte 2nd byte 3rd byte 4th byte 
00000000 00000000 00000000 00000001 

我想它,使它看起来像这样:

4th byte 3rd byte 2nd byte 1st byte 
00000001 00000000 00000000 00000000 

因此最低有效值的字节首先出现。我在想你可以使用for循环,但我不确定如何在C++中移位位/字节。例如,如果用户输入1,我不得不像上面的例子那样移动它的位,我不知道如何将1转换为位,然后移位。任何人都可以将我指向正确的方向吗?谢谢!

+2

@NPE怎么能说是重复的,如果它甚至不是同日而语? –

+1

因为大多数(如果不是所有)关于数字和操作的规则都是从C到C++的? – cHao

+0

@LuchianGrigore:当然,但在我看来,它仍然是重复的,因为它明确地说明了“移位和字节”,而不是“如何以奇特的C++风格来做这件事”。当然,社区可以另外做出决定。 – NPE

回答

3

<<>>是C和大多数其他C风格语言中的按位移运算符。

一种方式做你想要的是:

int value = 1; 
uint x = (uint)value; 
int valueShifted = 
    (x << 24) |    // Move 4th byte to 1st 
    ((x << 8) & 0x00ff0000) | // Move 2nd byte to 3rd 
    ((x >> 8) & 0x0000ff00) | // Move 3rd byte to 2nd 
    (x >> 24);     // Move 4th byte to 1st 
+0

我最初删除了我的答案,因为我认为这是正确的,但是这显示UB值大。 –

+0

我认为这不利于否定。 –

+0

*可否*否定否定,是的。在技​​术上左移一个负数可以调用UB,在大多数系统上右移一个负数会在1秒内改变。如果int是无符号的,也许... – cHao

2
uint32_t n = 0x00000001; 
std::reverse((char*)&n, (char*)(&n + 1)); 
assert(n == 0x01000000); 
+0

当字符不是8位大小时会变得很奇怪。例如,如果整数和字符都是32位,则倒转不起作用。 – cHao

+0

@cHao'C++标准保证1 == sizeof(char)'并且在问题中我们有32位'unsigned int'类型,那么如何使用例如7位字符来模拟它呢? – BigBoss

+0

'sizeof(char)== 1'只承诺char是一个字节;它承诺没有关于该字节的大小。该标准要求*每字节至少* 8位,但允许更多。已经(并且在特殊情况下仍然存在)具有8,9,16,32,36,甚至64比特字节的系统。在我的32位示例中,sizeof(int)== 1'。用一个字节,就没有任何交换。 – cHao

0

移位与<<>>运营商来完成。再加上逐位AND(&)和OR(|)运算符,你可以做你想做的:

int value = 1; 
int shifted = value << 24 | (value & 0x0000ff00) << 8 | (value 0x00ff0000) >> 8 | (value 0xff000000) >> 24; 
+0

我认为这是“价值”的大值的UB。 –

+0

“UB”是什么意思? –

+0

未定义的行为 –