アプリケーション開発ポータルサイト
ServerNote.NET
カテゴリー【C/C++
【C言語】ビットフラグ演算でデータの特徴を管理する
POSTED BY
2023-06-04

この人は男だとか女だとか、学生なのかそうでないのかとか、判断が2通り程度のものは、変数1つづつ割り当てるよりもビットフラグを使ったほうが、複数の属性を1つの変数で管理できるので便利である。

上記の例を変数1つづつにすると以下のようになるが

struct {
int is_male; /* 男かどうか 1なら男 */
int is_student; /* 学生かどうか 1なら学生 */
} flag;

flag.is_male = 0; /* 女性である */
flag.is_student = 1; /* 学生である */

冗長でわかりづらい。以下のようにビットフラグにするとすっきりする。

#define IS_MALE 0x00000001
#define IS_FEMALE 0x00000002
#define IS_STUDENT 0x00000010

int flag = IS_FEMALE | IS_STUDENT; /* 女性であり学生であると一度に保存できる */

標準C言語には2進数表記はない(はず)なので、16進数でビット定義する。1バイトは2ケタ(0x00)で表せ、それぞれのケタは1、2、4、8のビットがセット可能、つまり1ケタにつき4つの属性を定義できる。8まで使ってしまったら、次のケタを使う。

必要なケタ数まで変数幅を取るが、見た目わかりやすいので通常4バイト幅がおすすめ。(0x00000000)。この場合保存先変数はuint32_tやintになる。

属性の保存は複数属性を1度にセットまたは追加セットする場合OR演算子(|)でセットし、その属性が立っているのかどうかのチェックはAND演算子(&)で行えばよい。

以下、都道府県属性のセットとチェックのサンプルコード。都道府県は大量にあるのでビットフラグにするのは全く適切ではない(普通数値で管理する)が、他に適当なフラグ繰り上がり例を思いつかなかったので。

C/C++bitflag.cGitHub Source
#include <stdio.h>
#include <stdint.h>

/* 4バイトフラグ */

#define F_TOKYO    0x00000001
#define F_SAITAMA  0x00000002
#define F_CHIBA    0x00000004
#define F_KANAGAWA  0x00000008
#define F_IBARAKI  0x00000010
#define F_TOCHIGI  0x00000020
#define F_GUNNMA  0x00000040
#define F_YAMANASHI  0x00000080
#define F_SHIZUOKA  0x00000100

int main(int argc, char **argv) {

  uint32_t flag; /* 4バイトフラグ変数 */

  flag = F_TOKYO | F_TOCHIGI; /* 東京と栃木のビットON */

  if(flag & F_TOCHIGI) {
    printf("flag includes F_TOCHIGI\n");
  }

  if(flag & F_TOKYO) {
    printf("flag includes F_TOKYO\n");
  }

  if(flag & F_GUNNMA) {
    printf("flag includes F_GUNNMA\n");
  }

  flag |= F_YAMANASHI; /* 山梨を追加セット */

  if(flag & F_YAMANASHI) {
    printf("flag includes F_YAMANASHI\n");
  }

  return 0;
}

コンパイル、実行結果

gcc bitflag.c

 ./a.out

flag includes F_TOCHIGI
flag includes F_TOKYO
flag includes F_YAMANASHI

F_GUNNMAはセットしていないので出力されない。F_YAMANASHIをOR演算子で追加セットしているのがポイント。

※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!
ご連絡は以下アドレスまでお願いします★

【キーワード検索】