0

次のコードを考えてみましょう

#include <stdio.h>
#include <iostream>
using namespace std;
typedef struct bf_{
    unsigned x:4;
    unsigned y:4;
    unsigned z:4;
    unsigned  w:4;
    }bf;
int main(){
    unsigned short i=8;
    unsigned short j=9;
    bf* bitfields=(bf *)&i;
    bf*bit=(bf*)&j;
    bitfields->w=12;
    printf("%d\n",bitfields->x);
    printf("%d\n",bit->y);
    printf("%d\n",bitfields->w);



     return 0;
}

このフラグメント

unsigned short j=9;
bf*bit=(bf*)&j;
printf("%d\n",bit->y);

私は、たとえばこの場所の後に、このコードのいくつかの興味深い特徴を推測した後に追加しました

bf* bitfields=(bf *)&i;

8を出力する書き込みprintf("%d\n",bitfields->x);を行うと、ポインタと参照を使用してiの値がxに付与されることを理解しているため、たとえば8を出力すると、bitfiled->y0が書き込まれるため、2番目の要素変数jを導入してbfstructerの新しいインスタンスを作成します。 jを参照してから、ステートメントbit-> yは9を書き込む必要があります。これは、私が理解しているように、順序定義ですが、なぜ0になるのでしょうか。このコードがどのように機能するか説明してください。私は英語を話せませんので、英語が下手でごめんなさい

4

2 に答える 2

3

まず、このコードには参照が使用されていません。この&コンテキストのように、(型名の一部としてではなく) 単項演算子として使用される文字は、「address-of」を意味します。「への参照」ではなく&i、「のアドレス」も同様です。ii

bf構造体として値 9 を使用すると value をy取得する必要があるという考えをどこで得ているのかわかりません9。これを書くとき:

bf* bitfields=(bf *)&i;

何が起こるかというと、コンパイラに「メモリ位置の値を構造体&iであるかのように扱う」ように指示していることです。構造体は、最下位 (右端) ビットから開始して、最初の 4 ビットが値、2 番目の 4 ビットが値、3 番目の 4 ビットが値、というbfように定義されます。bfxyz

したがって、その位置の値&i8であり、16 ビット バイナリの 8 は

0000 0000 0000 1000 

のフィールドは次のbitfieldsようになります。

0000 0000 0000 1000 
  w    z    y    x

したがって、x(4 ビットの符号なし整数) の値は 8 で、yz、およびの値wは 0 です。

書く場合には

bf*bit=(bf*)&j;

値が 9 であることを除いて、上記と同じことを行っているため、割り当ては次のようになります。

0000 0000 0000 1001 
  w    z    y    x

xは 9 で、その他の値は 0 のままです。

yの代わりに値 9 を割り当てたい場合x、割り当ては次のようにする必要があります。

0000 0000 1001 0000 
  w    z    y    x

したがって、使用する必要がある値は、16 ビット バイナリ表現の値です。

0000 0000 1001 0000 

これは 144 です。したがって、j = 144の代わりにlet を使用するとj = 9、それbit->yが 9 であり、 の他のすべてのフィールドbitが 0 であることがわかります。

于 2010-09-27T15:14:42.917 に答える
0

構造体やクラスのコンパイル時に発生するパッキングが原因だと思います。次のリンクを参照してください。

http://msdn.microsoft.com/en-us/library/83ythb65.aspx#vclrfhowalignworkswithdatapacking
http://msdn.microsoft.com/en-us/library/2e70t5y1%28VS.80%29.aspx

デフォルトでは、コンパイル時の構造体のサイズは、そのメンバーの合計サイズと同じではありません。

于 2010-09-27T15:36:56.307 に答える