char bytes[2];
bytes[0] = 0; //0x00
bytes[1] = 24; //0x18
uint16_t* ptrU16 = (uint16_t*)bytes; // I expect it points to the memory block: 0x18
cout << *ptrU16 << endl; // I expect 24, but it is 6144
我的代码有什么问题?
你有一个小端机器。6144
是0x1800
。当您的机器在内存中表示 16 位值0x0018
时,它会将0x18
字节放在第一位,然后将0x00
字节放在第二位,因此当您将两个字节序列解释0x0018
为 auint16_t
时,它会给您6144
(ie 0x1800
),而不是24
(ie 0x0018
)。
如果您更改为:
bytes[0] = 24;
bytes[1] = 0;
您可能会看到您期望的结果。
如果你真的想得到你期望的结果,那么你要么必须手动计算它,例如:
uint16_t n = (bytes[1] << 8) + bytes[0];
或者,更一般地说:
char bytes[] = {0x18, 0x00};
uint16_t n = 0;
for ( size_t i = 0; i < 2; ++i ) {
n += bytes[i] << 8 * i;
}
std::cout << n << std::endl;
或者您可以使用类似的函数ntohs()
,因为网络字节顺序是大端。
您可能想查看该ntohs()
功能。(“网络到主机字节顺序转换”)。您已经以大端模式插入数据,这在传统上也是网络字节顺序。无论您在哪个主机上,ntohs() 函数都应该返回您期望的值。有一个从主机到网络顺序的镜像功能。
#include <arpa/inet.h>
...
cout << htons(*ptrU16) << endl;
应该可以工作并且可以跨系统移植。(即应该适用于 Power、ARM、X86、Alpha 等)。