从 char[2] 转换为短时反转字节顺序

inverted byte order when casting from char[2] to short

本文关键字:字节 顺序 char 转换      更新时间:2023-10-16

我所拥有的是这个

struct Record
{
unsigned char cat;
unsigned char len[2]={0x00, 0x1b};  // can't put short here because that 
                                   // whould change the size of the struct
unsigned char dat[253];
};
Record record;
unsigned short recordlen = *((unsigned short*)record.len);

这会导致recordlen=0x1b00而不是0x001b

*reinterpret_cast<unsigned short*>(record.len)相同

你能解释一下为什么吗?我应该怎么做?

你遇到的叫做"字节序"。在 x86 中,所有数值变量都存储为"小端序",这意味着最低有效字节排在第一位。

从维基百科页面:

小端系统具有以下特性:可以在不使用不同地址的情况下以不同的长度从内存中读取相同的值。

这取决于 CPU 的字节序。见维基百科。

在您的情况下,您有"小字节序",这意味着最低有效字节排在第一位。当您想将数字转换为不同的字节大小时,这很方便:如果您使用长整型来表示短数字,则其表示形式与短数字相同,只是末尾有额外的零。

你能解释一下为什么吗?

因为您不能假设计算机体系结构的特定字节序。

自然的后续问题是你怎么做。幸运的是,您可以通过调用这些函数之一来强制特定的字节顺序 htonlhtonsntohlntohs 。无论您运行它们的计算机体系结构如何,它们都可以工作:

在发送端,从主机顺序转换为网络顺序

;在接收端,从网络顺序转换为主机顺序。

// Sending end
unsigned short recordlen = calculate_len();
*reinterpret_cast<unsigned short*>(record.len) = htons(recordlen);
// Receiving end
unsigned short recordlen = ntohs(*reinterpret_cast<unsigned short*>(record.len));
unsigned short recordlen = *((unsigned short*)record.len);

这被打破了。 record.len并没有指向unsigned short.告诉编译器它只是在撒谎。

我想你想要:

unsigned short recordlen = static_cast<unsigned short>(record.len[0]) * 256 +
    static_cast<unsigned short>(record.len[1]);

或者,如果您更喜欢它:

unsigned short recordlen = (static_cast<unsigned short>(record.len[0]) << 8) |
    static_cast<unsigned short>(record.len[1]);

如果没有,请编写您真正想要的任何代码。