13

次のタイプの構造体があります

typedef struct
{
unsigned int a : 8;
unsigned int b : 6;
unsigned int c : 2;
}x, *ptr;

私がやりたいことは、フィールド c の値を変更することです。

私は次のようなことをします

x structure = { 0 };
x->c = 1;

メモリ マップを見ると、00 01が見つかるはずですが、代わりに00 40が見つかります。2番目のバイトを配置するときに、cフィールドを最下位ビットに、bフィールドを最上位ビットに配置するように見えます。これは、GCC コンパイラと Windows コンパイラの両方で見られます。

今のところ、私がしていることは次のとおりです。これは正常に機能しています。

unsigned char ptr2 = (unsigned char*) ptr
*(ptr2 + 1)  &= 0xFC
*(ptr2 + 1)  |= 0x01

メモリマップの見方が間違っていますか? ご協力ありがとうございました。

4

4 に答える 4

7

これが古いものであることは承知していますが、私の考えを追加したいと思います。

  1. C のヘッダーは、オブジェクト間で使用できるように意図されています。つまり、コンパイラはある程度一貫している必要があります。

  2. 私の経験では、ビットフィールドは常に LSB 順で表示されています。これにより、ビットが c:b:a の MSB->LSB 順になります。

バイトオーダーで読み取った 16 ビットは「00 40」です。リトルエンディアンから変換すると、これは 0x4000 の 16 ビット値です。

これは:

c == [15:14] == b'01
b == [13:8] == 0
a == [7:0] == 0
于 2016-10-13T02:06:03.560 に答える
0

メモリは常に、基礎となるマシン構造 (エンディアン) と、コンパイラが実行している構造をパック/配置するための戦略に依存します。

于 2013-10-15T08:36:33.057 に答える