본문 바로가기

무언가 만들기 위한 지식/C,C++,Embedded C

[C, Embedded C] 비트플래그(bit flag)

현재의 프로그램의 상태, 사용자가 정한 모드, 인터럽트 등에서는 상태를 1과 0으로 나타낼 수 있는 플래그가 필요하다.
이러한 플래그는 참, 거짓만 필요로 하기 때문에 1bit만 공간이 주어지면 된다.
하지만 C언어에는 bool type이 없기 때문에 보통 int 변수를 사용하게 된다.

int Type은 총 32bit로 구성되어 있는데 1bit만 사용한다는 것은 메모리의 낭비를 의미한다. 즉 31bit가 낭비되고 있는 것이다.
이에 사용되는 것이 바로 비트 플래그이다.

(사용자 정의에 의해서 하나의 int Type을 쪼개서 비트연산으로 각 모드로 사용해도 상관없으나, Struct을 이용한 비트플래그를 사용하면 가독성이 좋아진다!)

비트플래그는 구조체 안에서만 생성 가능하고 주로 unsigned int로 선언하야 사용한다.
컴파일러에 따라 int만 지원하기도 하고, 모든 정수형 데이터를 지원하기도 한다고 한다.

간단한 예를 보면 다음과 같다.
[작성환경 : Window XP   작성툴 : Visual Studio 6.0   컴파일러 : Visual Studio 6.0    사용언어 : C]
 
struct Test내에는 4개의 Type이 있는데 (":"-세미콜론)으로 비트 수를 정해준다.
1이라는 의미는 하나의 비트를 사용하겠다는 의미이고, 4를 쓰면 현재 변수에 4개의 비트를 할당한다는 의미이다.
9 Line에서는 초기화를 해주었고, 10 Line에서는 크기를 출력해보니 int Type인 4가 출력됨을 아래 그림에서 확인할 수 있다.
11 Line은 temp로부터 4byte를 읽어 출력해본 모습이다. 0,1,1,1로 초기화를 하였는데 이는 1110으로 인식되어(32bit 내에서) 출력해보면 14가 나온 모습을 볼 수 있다.
1byte에 할당된 각 bit의 모습은 다음과 같다.




<상단 소스 결과값>


위 모습은 Struct 내에서 bit를 변경해본 결과이다. B를 31bit로 할당할 경우 즉 A와 B를 합쳐서 32bit 이상일 경우에는 다음 32bit가 플래그로 잡힌다. Sizeof를 해보면 총 크기가 8 Byte로 나온 모습을 볼 수 있다. 또한 Struct에서 4byte만 읽어오면 이진수 10이 출력되어 2가 나온 모습을 볼 수 있다.

이 때 출력한 BitFlag Value는 컴퓨터마다 다를 수 있다.
CPU가 빅엔디언이냐, 리틀엔디언이냐에 따라 다르다. ARM계열은 빅엔디언, 인텔계열은 리틀엔디언이라고 한다.
간단하게 설명하면 리틀엔디언은 메모리에 데이터를 저장할때 bit를 작은 비트먼저 채워나가는 것이고 빅엔디언은 반대이다.
위는 노트북으로 돌린 것이라 리틀엔디언이 적용된 모습이고 처음 선언된 A서부터 낮은 Bit부터 채워나간 모습이다. 그 결과는 출력된 Value값에서 확인이 가능하다.

이 방법은 하드웨어 설정에서 유용하게 사용될 수 있고, 메모리 절약에 효과적이다. 하지만 개별 비트 처리를 위해서 내부적으로 쉬프트나 마스킹 연산이 수행되어 속도는 떨어 질 수 있다.