我正在玩小endian/big endian转换,发现了一些有点混乱但也很有趣的东西。
在第一个示例中,使用位移位来转换
uint32_t
. 基本上
第32章
整数到数组
uint8_t
并尝试访问每个字节和位移位。
uint32_t htonl(uint32_t x)
{
uint8_t *s = (uint8_t*)&x;
return (uint32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
}
但是,如果我尝试在
uint64_t
下面,编译器抛出一个警告,说明's[0]宽度小于56位,如下面的示例2所示。
示例2:
uint64_t htonl(uint64_t x)
{
uint8_t *s = (uint8_t*)&x;
return (uint64_t)(s[0] << 56 ......);
}
为了让它工作,我必须将每个字节都取到
因此,我可以在没有任何错误的情况下进行位移位,如下面的示例3所示。
uint64_t htonll2(uint64_t x)
{
uint64_t byte1 = x & 0xff00000000000000;
uint64_t byte2 = x & 0x00ff000000000000;
uint64_t byte3 = x & 0x0000ff0000000000;
uint64_t byte4 = x & 0x000000ff00000000;
uint64_t byte5 = x & 0x00000000ff000000;
uint64_t byte6 = x & 0x0000000000ff0000;
uint64_t byte7 = x & 0x000000000000ff00;
uint64_t byte8 = x & 0x00000000000000ff;
return (uint64_t)(byte1 >> 56 | byte2 >> 40 | byte3 >> 24 | byte4 >> 8 |
byte5 << 8 | byte6 << 24 | byte7 << 40 | byte8 << 56);
}
我有点困惑
Example #1
和
Example #2
,据我所知,两者
s[i]
单位8
大小,但不知何故,如果它只移动32位或更少,根本没有问题,但有一个问题,当移动像56位。我用GCC 8.3.0在Ubuntu上运行这个程序。
s[i]
在这种情况下变成32位数字?
sizeof(s[0])
当我向其中添加调试消息时为1。