工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> C言語

C言語ビットフィールド:メモリ効率を最大化するテクニック

ビットフィールドの必要性

CプログラムにTRUE/FALSE変数が多数含まれ、それらがstatusという構造体にグループ化されているとします:

struct {
    unsigned int widthValidated;
    unsigned int heightValidated;
} status;

この構造体は8バイトのメモリ空間を必要としますが、実際には各変数に0または1のみを格納します。Cプログラミング言語は、このような状況でメモリ空間をより効率的に利用する方法を提供します。

このような変数を構造体内で使用する場合、変数の幅を定義できます。これはCコンパイラに、そのビット数のみを使用することを伝えます。例えば、上記構造体は以下のように書き換えられます:

struct {
    unsigned int widthValidated : 1;
    unsigned int heightValidated : 1;
} status;

上記構造体ではstatus変数に4バイトのメモリ空間が必要ですが、実際には2ビットのみで値を格納できます。

幅1ビットの変数を最大32個使用しても、status構造体は4バイトを使用します。しかし33個になると、次のメモリスロットが割り当てられ、8バイトを使用し始めます。以下の例で概念を理解しましょう:

Live Demo
#include <stdio.h>
#include <string.h>

/* 通常の構造体 */
struct {
    unsigned int widthValidated;
    unsigned int heightValidated;
} status1;

/* ビットフィールドを持つ構造体 */
struct {
    unsigned int widthValidated : 1;
    unsigned int heightValidated : 1;
} status2;

int main() {
    printf("Memory size occupied by status1 : %d\n", sizeof(status1));
    printf("Memory size occupied by status2 : %d\n", sizeof(status2));
    return 0;
}

実行結果:

Memory size occupied by status1 : 8
Memory size occupied by status2 : 4

ビットフィールド宣言

構造体内でのビットフィールド宣言の形式:

struct {
    type [member_name] : width;
};

ビットフィールドの変数要素を説明する表:

番号要素と説明
1type
ビットフィールドの値の解釈を決定する整数型。int、signed int、unsigned intが指定可能。
2member_name
ビットフィールドの名前。
3width
ビットフィールドのビット数。指定された型のビット幅以下でなければならない。

事前定義された幅を持つ変数をビットフィールドと呼びます。ビットフィールドは1ビット以上を保持できます。例えば0〜7の値を格納する変数が必要なら、幅3ビットのビットフィールドとして定義できます:

struct {
    unsigned int age : 3;
} Age;

上記構造体定義は、age変数が値を格納するのに3ビットのみを使用することをCコンパイラに指示します。3ビットより多く使用しようとすると許可されません。以下の例を試してみましょう:

Live Demo
#include <stdio.h>
#include <string.h>

struct {
    unsigned int age : 3;
} Age;

int main() {
    Age.age = 4;
    printf("Sizeof(Age) : %d\n", sizeof(Age));
    printf("Age.age : %d\n", Age.age);
    Age.age = 7;
    printf("Age.age : %d\n", Age.age);
    Age.age = 8;  /* 3ビットを超える値 */
    printf("Age.age : %d\n", Age.age);
    return 0;
}

上記コードをコンパイルすると警告が出ますが、実行すると以下の結果になります:

Sizeof(Age) : 4
Age.age : 4
Age.age : 7
Age.age : 0

C言語

  1. C# ビット演算子とビットシフト演算子をマスターする:包括的ガイド
  2. C言語ユーザー定義関数の4つの実証済みパターン
  3. C言語で1次元・2次元配列を関数に渡す方法 – 実践ガイド
  4. C言語 構造体とポインタ: 実践ガイド
  5. C++構造体を実例で徹底解説
  6. C言語の関数マスター:構造、宣言、ベストプラクティス
  7. C言語可変長引数のマスター:実践ガイド
  8. C#のメソッド:定義、呼び出し、パラメータ渡し、再帰を完全解説
  9. MATLAB積分マスター:不定積分からリーマン和まで
  10. Javaのthisキーワード徹底解説:実践的な用法とコンストラクタ活用
  11. Javaカプセル化マスター:データ隠蔽の実践ガイド