C言語,ビット演算子を使用してフラグを設定する

スポンサーリンク

鍛錬 954

C言語,ビット演算子を使用してフラグを設定する

フラグを管理する方法の一つとして、ビット演算子を使用してビット列で管理する方法があります。

フラグとなるビット列を準備する方法

以下の例は、フラグとなるビット列を事前に準備しています。

それぞれの変数(TIMEOUT , DISCONNECT , STOP)に対し、ビット演算子「 << 」(左シフト) を利用して、数値の 1 を左シフトしています。

 
// フラグ(1)(TIMEOUT)
// 00000000 00000000 00000000 00000001 (int(32bit))
const int TIMEOUT = 1 << 0;

// フラグ(2)(DISCONNECT)
// 00000000 00000000 00000000 00000010 (int(32bit))
const int DISCONNECT = 1 << 1;

// フラグ(3)(STOP)
// 00000000 00000000 00000000 00000100 (int(32bit))
const int STOP = 1 << 2;
 

 
上記の設定により、各変数 TIMEOUT , DISCONNECT , STOP は以下の状態となります。

フラグ(1)
(TIMEOUT)
00000000 00000000 00000000 00000001
フラグ(2)
(DISCONNECT)
00000000 00000000 00000000 00000010
フラグ(3)
(STOP)
00000000 00000000 00000000 00000100

フラグを設定する方法

以下の例は、フラグを設定しています。

ビット演算子「 | 」(OR) を利用して、指定したビットを立てています。

 
int flag = 0;
flag |= TIMEOUT;	// フラグ(1)(TIMEOUT)を設定
 

上記の設定を行うと、変数 flag は以下の状態となります。

フラグ(1)
(TIMEOUT)
00000000 00000000 00000000 00000001
変数 flag の状態(設定前)
00000000 00000000 00000000 00000000
変数 flag の状態(設定後)
00000000 00000000 00000000 00000001

 
以下の例は、続けて他のフラグを設定しています。

 
flag |= STOP;		// フラグ(3)(STOP)を設定
 
フラグ(3)
(STOP)
00000000 00000000 00000000 00000100
変数 flag の状態(設定前)
00000000 00000000 00000000 00000001
変数 flag の状態(設定後)
00000000 00000000 00000000 00000101

 

 
flag |= DISCONNECT;	// フラグ(2)(DISCONNECT)を設定
 
フラグ(2)
(DISCONNECT)
00000000 00000000 00000000 00000010
変数 flag の状態(設定前)
00000000 00000000 00000000 00000101
変数 flag の状態(設定後)
00000000 00000000 00000000 00000111

フラグの設定状態を確認する方法

以下の例は、フラグの状態を確認しています。

ビット演算子「 & 」(and) を利用して、指定したビットが立っているのかを確認しています。

 
// フラグ(1)(TIMEOUT)
if (flag & TIMEOUT) {
	printf("フラグが立っている\n");
}
else {
	printf("立っていない\n");
}

// フラグ(2)(DISCONNECT)
if (flag & DISCONNECT) {
	printf("フラグが立っている\n");
}
else {
	printf("立っていない\n");
}

// フラグ(3)(STOP)
if (flag & STOP) {
	printf("フラグが立っている\n");
}
else {
	printf("立っていない\n");
}
 

フラグをクリアする方法

以下の例は、フラグをクリアしています。

ビット演算子「 ~ 」(反転) を利用してフラグのビットを反転させた後、ビット演算子「 & 」(and) を利用してフラグをクリアしています。

 
flag &= ~DISCONNECT;	// フラグ(2)(DISCONNECT)をクリア
 

上記の設定を行うと、変数 flag は以下の状態となります。

フラグ(2)
(DISCONNECT)
00000000 00000000 00000000 00000010
変数 flag の状態(クリア前)
00000000 00000000 00000000 00000111
変数 flag の状態(クリア後)
00000000 00000000 00000000 00000101

 
以下の例は、続けて他のフラグをクリアしています。

 
flag &= ~TIMEOUT;		// フラグ(1)(TIMEOUT)をクリア
 
フラグ(1)
(TIMEOUT)
00000000 00000000 00000000 00000001
変数 flag の状態(クリア前)
00000000 00000000 00000000 00000101
変数 flag の状態(クリア後)
00000000 00000000 00000000 00000100

 

 
flag &= ~STOP;			// フラグ(3)(STOP)をクリア
 
フラグ(3)
(STOP)
00000000 00000000 00000000 00000100
変数 flag の状態(クリア前)
00000000 00000000 00000000 00000100
変数 flag の状態(クリア後)
00000000 00000000 00000000 00000000
スポンサーリンク

プログラム

以下は、フラグを管理するプログラム、set_bitflag.c です。

今回は、int 型(32 bit)の変数に対し、次の順序でフラグを操作しています。

(1) フラグを初期化

フラグの状況
(初期化直後)
00000000 00000000 00000000 00000000

(2) フラグを設定

フラグの状況
(3,5,8 ビット目にフラグ設定後)
00000000 00000000 00000000 10010100

(3) フラグをクリア

フラグの状況
(5 ビット目のフラグをクリアした後)
00000000 00000000 00000000 10000100
// include
#include <stdio.h>

// preprocessor
const int AAA = 1 << 0;	// 00000000 00000000 00000000 00000001
const int BBB = 1 << 1;	// 00000000 00000000 00000000 00000010
const int CCC = 1 << 2;	// 00000000 00000000 00000000 00000100
const int DDD = 1 << 3;	// 00000000 00000000 00000000 00001000
const int EEE = 1 << 4;	// 00000000 00000000 00000000 00010000
const int FFF = 1 << 5;	// 00000000 00000000 00000000 00100000
const int GGG = 1 << 6;	// 00000000 00000000 00000000 01000000
const int HHH = 1 << 7;	// 00000000 00000000 00000000 10000000

// prototype
void PrintFlag(int flag, int size);

// main
int main(void)
{
	int flag;
	
	// フラグ初期化
	flag = 0;
	
	// フラグの設定状況を確認
	PrintFlag(flag, sizeof(int));
	
	// フラグをセット
	flag |= CCC;	// 3bit目
	flag |= EEE;	// 5bit目
	flag |= HHH;	// 8bit目
	
	// フラグの状況を確認
	PrintFlag(flag, sizeof(int));
	
	// 5bit目のフラグをクリア
	flag &= ~EEE;	// 5bit目
	
	// フラグの設定状況を確認
	PrintFlag(flag, sizeof(int));
	
	return 0;
}

// ========================================
// @brief  フラグの設定状況を表示する
// @param  flag [in],確認するフラグ
// @param  size [in],フラグの型サイズ
// @return 無し
// @note   無し
// ========================================
void PrintFlag(int flag, int size)
{
	int bit;
	int i, cnt;
	int bit_check;
	
	bit = (size * 8) - 1;
	
	// フラグの設定状況を表示
	cnt = 0;
	for (i = bit; i >= 0; i--) {
		// 表示用
		if (cnt % 8 == 0 && cnt >= 8) {
			printf(" ");
		}
		cnt++;
		
		// 確認するビットを設定
		bit_check = 1 << i;
		
		// フラグが立っている場合
		if (flag & bit_check) {
			printf("1");
		}
		// フラグが立っていない場合
		else {
			printf("0");
		}
	}
	printf("\n");
}
スポンサーリンク

実行結果

以下は、プログラム set_bitflag.c を実行しています。

***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ gcc -Wall -Wextra set_bitflag.c -o set_bitflag
***@ubuntu:~/***/test/c$ ./set_bitflag
00000000 00000000 00000000 00000000
00000000 00000000 00000000 10010100
00000000 00000000 00000000 10000100

 
上記に示した通り、ビット演算子を使用してフラグを設定することができました。

タイトルとURLをコピーしました