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 では、すべての数値変数は「リトル エンディアン」で格納されます。つまり、最下位バイトが最初に来ます。

ウィキペディアのページから:

リトルエンディアン システムには、異なるアドレスを使用せずに同じ値を異なる長さでメモリから読み取ることができるという特性があります。

于 2013-01-29T22:38:55.023 に答える
4

これは、CPU のエンディアンに依存します。ウィキペディアを参照してください。

あなたの場合、「リトルエンディアン」があります。これは、最下位バイトが最初に来ることを意味します。これは、数値を異なるバイト サイズに変換する場合に便利です。long int を使用して short 数値を表す場合、その表現は short 数値の場合と同じですが、末尾にゼロが追加されるだけです。

于 2013-01-29T22:38:08.417 に答える
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 に答える
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 に答える