Nodachisoft Nodachi Sword Icon
  
@あまじ✎ 2021年3月3日に更新

第2章52 ビットフィールドを扱う

イチからゲーム作りで覚えるC言語
第2章51 ソートの仕組み(バブルソート) : PREV
NEXT : 第2章53 関数ポインタを扱う :

概要

C言語のビットフィールドの使い方について確認していきましょう。

TRUE か FALSE だけのデータを扱う時は 0 か 1 だけを記録する、 1 ビットあれば十分ですよね。

これを int 型で扱うと、私の環境では 4バイト、つまり32ビットのメモリサイズが必要です。 もっとも小さな char 型で扱っても、 1バイト、つまり 4 ビット必要で、 3 ビット無駄にメモリが必要となります。

この無駄な部分をビットフィールド機能を使うことで効率よく扱えることがあります。

通常のケース

例として、キャラクタ毎に4つの状態をもっていることを考えます。 今回は適当に、毒、睡魔、視力低下、強化の4つとします。

各ステータスは 0 なら FALSE(その状態ではない)、1 なら TRUE (その状態である)として扱うことを想定します。

ステータスは構造体(CharacterStatus型)を定義して、使いやすくまとめます。

 
before_bitfield.c
#include <stdio.h>
typedef struct __CharacterStatus {
    unsigned int isPoison;  // 毒状態
    unsigned int isSleep;   // 睡魔状態
    unsigned int isBlind;   // 視力低下状態
    unsigned int isPowerup; // 強化状態
} CharacterStatus;

int main() {
    printf("キャラクタステータスの構造体のサイズは %zu バイト。\n", sizeof(CharacterStatus));
}

実行すると下のような結果になりました。

実行結果
キャラクタステータスの構造体のサイズは 16 バイト。

一人のキャラクタステータスを記録するために、int型のメンバを 4 個もつので、4 x 4 = 16 バイト必要となることがわかります。

これをビットフィールドを使って書き換えてみます。

 
bitfield_ex.c
#include <stdio.h>
typedef struct {
    unsigned int isPoison :1;  // 毒状態
    unsigned int isSleep :1;   // 睡魔状態
    unsigned int isBlind :1;   // 視力低下状態
    unsigned int isPowerup :1; // 強化状態
} CharacterStatus;

int main() {
    printf("キャラクタステータスの構造体のサイズは %zu バイト。\n", sizeof(CharacterStatus));
}

構造体 CharacterStatus の定義の中で、各メンバを定義するときに、 末尾に :1 という記載が増えているかと思います。

この :1 という記載は 1 ビットの領域をこの変数で使用します

という命令となります。この記載部分のことをビットフィールド(bit-fields)の指定と呼びます。

1 ビットのビットフィールド(ビット単位でのメモリ領域)を unsinged int に指定すると、 割り当てられた変数は 0 か 1 のみ扱う変数となります。

このプログラムの実行結果は下のようになります。

実行結果
キャラクタステータスの構造体のサイズは 4 バイト。

実際に使っているビット数は 4 ビットのみですが、4バイト(32ビット)使用しているとの結果がでました。

これはある程度のサイズの単位でメモリの塊が確保されるためです。この最小の単位は記憶域単位と呼ばれ、具体的なサイズは処理系によってことなります。

今回は 4 つの True / False を記録するメンバのみですが、32個までのメンバをわずか 4バイト(32ビット)の領域に記憶できます。

非常に大きなデータはこういったビット操作をすることで、効率的にメモリ上に格納できるので、使いこなせると役に立つときがあります!

参考

(英語)C11仕様書 - N1570 - 3.14 - memory location

イチからゲーム作りで覚えるC言語
第2章51 ソートの仕組み(バブルソート) : PREV
NEXT : 第2章53 関数ポインタを扱う :
 
 
送信しました!

コメント、ありがとうございます。

なんかエラーでした

ごめんなさい。エラーでうまく送信できませんでした。ご迷惑をおかけします。しばらくおいてから再度送信を試していただくか、以下から DM などでご連絡頂ければと思います。

Twitter:@NodachiSoft_jp
お名前:
 
連絡先:
 
メッセージ:
 
戻る
内容の確認!

以下の内容でコメントを送信します。よろしければ、「送信」を押してください。修正する場合は「戻る」を押してください

お名前:
 
連絡先:
 
メッセージ:
 
Roboto からの操作ではないという確認のため確認キーを入れてください。
確認キー=95
戻る
 / 
送信確認へ
コメント欄
コメント送信確認へ

関連ありそうな記事(5件)です!

第1章01 Visual Studio Community 2019 のインストール手順

#C11仕様#C言語#ゲームプログラミング✎ 2021-08-08
C言語でプログラミングをするために、無料で使える Visual Studio Community を使った開発環境を揃えていく手順や注意点をお話しています。
目次
第2章52 ビットフィールドを扱う
第2章52 ビットフィールドを扱う
概要
概要
通常のケース
通常のケース
参考
参考
Nodachisoft © 2021