1. ホーム
  2. c++

C言語ではいつビットフィールドを使うのか?

2023-10-11 18:30:27

質問

なぜビットフィールドを使う必要があるのか」という質問について、Googleで検索したところ、ビットフィールドはフラグに使われることがわかりました。 今、私は好奇心でいっぱいです。

  1. ビットフィールドの実用的な使い方はこれだけなのでしょうか?
  2. スペースを節約するためにビットフィールドを使用する必要があるのでしょうか?

本から見たビットフィールドの定義方法。

struct {
    unsigned int is_keyword : 1; 
    unsigned int is_extern :  1; 
    unsigned int is_static : 1;
} flags;

  1. なぜintを使うのですか?
  2. どのくらいの容量を占有しているのでしょうか?

私は、なぜ私たちが int を使うのか、しかし short よりも小さいもの、あるいは int .

  1. 私の理解では、1ビットだけがメモリに占有され、unsigned intの値全体は占有されないと思います。これは正しいのでしょうか?

どのように解決するのですか?

<ブロッククオート

さて、ビットフィールドの実用的な使い方はフラグだけなのでしょうか?

いいえ、ビットフィールドの使用方法はフラグだけではありません。フラグの方がより一般的ですが、1 ビットより大きな値を格納するために使用することもできます。例えば

typedef enum {
    NORTH = 0,
    EAST = 1,
    SOUTH = 2,
    WEST = 3
} directionValues;

struct {
    unsigned int alice_dir : 2;
    unsigned int bob_dir : 2;
} directions;

スペースを節約するためにビットフィールドを使用する必要がありますか?

ビットフィールドはスペースを節約します。また、バイトアラインされていない値を設定する簡単な方法もあります。ビットシフトやビット演算を使うのではなく、フィールドを設定するのと同じ構文で struct . これにより、可読性が向上します。ビットフィールドの場合、次のように書くことができます。

directions.alice_dir = WEST;
directions.bob_dir = SOUTH;

しかし,複数の独立した値を1つの int (または他の型)の空間にビットフィールドなしで複数の独立した値を格納するには、次のような書き方が必要になります。

#define ALICE_OFFSET 0
#define BOB_OFFSET 2
directions &= ~(3<<ALICE_OFFSET); // clear Alice's bits
directions |= WEST<<ALICE_OFFSET; // set Alice's bits to WEST
directions &= ~(3<<BOB_OFFSET);   // clear Bob's bits
directions |= SOUTH<<BOB_OFFSET;  // set Bob's bits to SOUTH

ビットフィールドの可読性を向上させることは、あちこちで数バイトを節約することよりも重要であることは間違いないでしょう。

なぜintを使うのでしょうか?どれくらいの容量を占有しているのでしょうか?

全体の空間は int が占有されます。私たちは int を使うのは、多くの場合、それは本当に重要ではないからです。1つの値に対して、1バイトや2バイトではなく4バイトを使っても、おそらくユーザーは気づかないでしょう。プラットフォームによっては、サイズはより重要であり、より少ないスペースを取る他のデータ型 ( char , short , uint8_t など)。

私の理解では、1ビットだけがメモリに占有され、unsigned intの値全体は占有されないと思います。これは正しいのでしょうか?

いいえ、それは正しくありません。全体の unsigned int は、たとえ 8 ビットしか使っていなくても存在します。