2
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

私のコードで何が問題になっていますか?

4

2 に答える 2

4

リトル エンディアン マシンがあります。6144です0x18000x0018マシンがメモリ内の 16 ビット値を表す場合、0x18バイトを最初に配置し、0x00バイトを 2 番目に配置するため、2 バイト シーケンス0x0018を として解釈するuint16_t6144(つまり0x1800)、そうではありません24(つまり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()ネットワークのバイトオーダーはビッグエンディアンであるため、のような関数を使用することもできます。

于 2014-12-19T02:36:32.073 に答える
0

ntohs()関数を調べてみるとよいでしょう。(「ネットワークからホストへのバイト順変換」)。ビッグ エンディアン モードでデータをプラグインしました。これは、伝統的にネットワーク バイト オーダーでもあります。どのホストを使用していても、ntohs() 関数は期待どおりの値を返す必要があります。ホストからネットワークの順序に移行するためのミラー機能があります。

#include <arpa/inet.h>
...
cout << htons(*ptrU16) << endl;

システム間で動作し、移植可能でなければなりません。(つまり、Power、ARM、X86、Alpha などで動作するはずです)。

于 2014-12-19T03:04:54.353 に答える