0

私はビット演算子をよりよく理解しようとしています。uint32_tバイトごとに出力しようとしているタイプがいくつかあります。それを行うコードは次のとおりです。

void printByteWise(uint32_t num) {

  printf("byte 1 = %u\n", (num & 0xFF000000));
  printf("byte 2 = %u\n", (num & 0x00FF0000));
  printf("byte 3 = %u\n", (num & 0x0000FF00));
  printf("byte 4 = %u\n", (num & 0x000000FF));
}

上記のコードサンプルで9と言いnumます。次に、バイト配列は次のようにメモリに格納する必要があります:(
09 00 00 00アドレスの昇順)。もしそうなら、出力は次のようになります:
byte 1 = 09
byte 2 = 00
byte 3 = 00
byte 4 = 00
しかし、私が得る出力は次のとおりです:

byte 1 = 0
byte 2 = 0
byte 3 = 0
byte 4 = 9

私は次のように取得されるリトルエンディアンのシステムを使用しています。

int is_bigEndian() {
  int i = 1;
  char *low = (char *) (&i);
  return *low ? 0 : 1;
}  

この動作は正しいですか?なぜ私はこの振る舞いを見ているのですか?

4

2 に答える 2

3

両方のオペランドが同じエンディアンであることを忘れないでください。

リトルエンディアンでは、はい、9 は 0x09000000 として保存されます。次に、0xFF000000 でマスキングします。これは、0x000000FF としてメモリに保存されるため、そのパターンでマスクとして使用されます。

効果を完全に確認したい場合は、Ali Veli が言うように、charポインターを使用してメモリをバイト単位で反復処理します。

于 2013-02-12T10:44:11.777 に答える
0

ビット演算子では、オペランドは実際にはメモリ内ではなくレジスタ内の数値です。したがって、ここではエンディアンとは何の関係もありません。これは予期されたものであり、正しいものです。

アドレスを char * などにキャストして変数を検査し、ポインターの値を増やしてバイトを超えると、毎回メモリからバイトを読み取ることになり (キャッシュが透過的であるとしましょう)、そこに効果が見られます。エンディアンの。

于 2013-02-12T10:41:09.067 に答える