1

我有的是这个

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)

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

4

4 回答 4

5

您遇到的称为“字节顺序”。在 x86 中,所有数值变量都存储为“小端”,这意味着最低有效字节在前。

从维基百科页面:

little-endian 系统的特性是可以从内存中读取不同长度的相同值,而无需使用不同的地址。

于 2013-01-29T22:38:55.023 回答
4

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

在您的情况下,您有“小端”,这意味着最不重要的字节排在第一位。当您想将数字转换为不同的字节大小时,这很方便:如果您使用 long int 来表示一个短数字,它的表示方式与它是一个短数字相同,只是它末尾有额外的零。

于 2013-01-29T22:38:08.417 回答
1
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]);

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

于 2013-01-29T22:44:01.547 回答
1

你能解释一下为什么吗?

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

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

在发送端,您将主机订单转换为网络订单;在接收端,您从网络订单转换为主机订单。

// 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));
于 2013-01-29T22:55:04.210 回答