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
。0x0018
マシンがメモリ内の 16 ビット値を表す場合、0x18
バイトを最初に配置し、0x00
バイトを 2 番目に配置するため、2 バイト シーケンス0x0018
を として解釈するuint16_t
と6144
(つまり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()
ネットワークのバイトオーダーはビッグエンディアンであるため、のような関数を使用することもできます。
ntohs()
関数を調べてみるとよいでしょう。(「ネットワークからホストへのバイト順変換」)。ビッグ エンディアン モードでデータをプラグインしました。これは、伝統的にネットワーク バイト オーダーでもあります。どのホストを使用していても、ntohs() 関数は期待どおりの値を返す必要があります。ホストからネットワークの順序に移行するためのミラー機能があります。
#include <arpa/inet.h>
...
cout << htons(*ptrU16) << endl;
システム間で動作し、移植可能でなければなりません。(つまり、Power、ARM、X86、Alpha などで動作するはずです)。