40
#include <stdio.h>

typedef struct size
{
        unsigned int a:1;
        unsigned int b:31;
        unsigned int c:1;
} mystruct;

int main()
{
        mystruct a;
        printf("%d", sizeof(a));
        return 0;
}
  • int b:31場合、出力は 8 です。
  • int b:1場合、出力は 4 です。
  • int b:32場合、出力は 12 です。

誰かがこの理由を説明できますか?

4

4 に答える 4

54

重要なのは順序です。次のコードは出力を提供します: 8

#include<stdio.h>

typedef struct size
{
        unsigned int b:32;
        unsigned int a:1;
        unsigned int c:1;
}mystruct;

int main(int argc, char const *argv[])
{
        mystruct a;
        printf("\n %lu \n",sizeof(a));
        return 0;
}

unsigned int は 32 ビット整数で、4 バイトを占有します。メモリはメモリ内で連続して割り当てられます。


オプション1:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:31;      // Will get accomodated in the First 4 bytes
unsigned int c:1;       // Second 4 bytes are allocated

出力: 8


オプション 2:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:32;      // Will NOT get accomodated in the First 4 bytes, Second 4 bytes are allocated
unsigned int c:1;       // Will NOT get accomodated in the Second 4 bytes, Third 4 bytes are allocated

出力: 12


オプション 3:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:1;       // Will get accomodated in the First 4 bytes
unsigned int c:1;       // Will get accomodated in the First 4 bytes

出力: 4


オプション 4:

unsigned int b:32;      // First 4 bytes are allocated
unsigned int a:1;       // Second 4 bytes are allocated
unsigned int c:1;       // Will get accomodated in the Second 4 bytes

出力: 8

于 2013-04-21T08:26:12.020 に答える
31

あなたはビットフィールドが何であるかを知っているかどうかは言いませんが、私はあなたが知っていると思います。

あなたの実装では、明らかにunsigned int32ビット整数であり、4バイトを占めています。これは、最初と2番目の例を説明しています。明らかに、合計33ビットの3ビットフィールドは1つに収まらないためunsigned int、最初の例では8バイトが必要です。合計3ビットの3ビットフィールドは確かにに適合しますunsigned int。したがって、2番目の例では4バイトのみです。

さらに、ビットフィールドは複数の整数にまたがることはできません。これは3番目の例を説明しています。それが標準の要件なのか、それとも実装の詳細なのか思い出せません。いずれにせよ、bは32ビットであるため、それ自体で全体を埋め、中央のビットの前後で、とunsigned intの両方を強制的に占有します。したがって、12バイト。acunsigned int

于 2010-11-09T02:32:41.873 に答える
11

Steve jessop's answerによると、役立つドキュメントをいくつか追加して彼の答えを満たすだけです。

構造体または共用体のメンバーは、可変に変更された型以外の完全なオブジェクト型を持つことができます。さらに、メンバーは、指定された数のビット (符号ビットがある場合はそれを含む) で構成されるように宣言できます。そのようなメンバーはビットフィールドと呼ばれ、その幅の前にコロンが付きます

実装では、ビットフィールドを保持するのに十分な大きさのアドレス指定可能なストレージユニットを割り当てることができます。十分なスペースが残っている場合、構造内の別のビットフィールドの直後に続くビットフィールドは、同じユニットの隣接するビットにパックされます。十分なスペースが残っていない場合、収まらないビットフィールドを次のユニットに配置するか、隣接するユニットとオーバーラップするかは実装定義です。ユニット内のビットフィールドの割り当て順序 (上位から下位、または下位から上位) は実装定義です。アドレス可能なストレージ ユニットのアラインメントは指定されていません。

構造体オブジェクト内で、非ビット フィールド メンバーとビット フィールドが存在するユニットには、宣言された順序で増加するアドレスがあります。適切に変換された構造体オブジェクトへのポインターは、その最初のメンバー (または、そのメンバーがビットフィールドの場合は、それが存在するユニット) を指し、その逆も同様です。構造体オブジェクト内に名前のないパディングがある場合がありますが、先頭にはありません。

——ISO/IEC 9899:201x 6.7.2.1

于 2012-12-23T04:06:53.273 に答える
10

アラインメント

コンパイラは、構造体のサイズを32ビットに丸め、各オブジェクトのサイズが32ビットを参照しようとする可能性があると同時に、ビットフィールドの順序を保持します。

したがって、中央に32ビットアイテムがあり、両側に1ビットアイテムがある場合、割り当てる32ビットワードは3つで、12バイトになります。

他の2つのケースでは、フィールドの順序を維持しながら、ビットフィールドシーケンスをパックできる32ビットオブジェクトの数が問題になります。

于 2010-11-09T02:33:37.787 に答える