강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

강진성님의 프로필 이미지
강진성

작성한 질문수

홍정모의 따라하며 배우는 C++

3.9 비트 플래그, 비트 마스크 사용법 Bit flags, Bit masks

비트 플래그 사용 이유가 잘 이해가지 않습니다.

작성

·

204

1

만약 아이템 8개에 대한 플래그를 사용하는 것이라고 가정해보면

bool 타입 플래그를 사용하면 1 * 8 = 8바이트가 필요함은 알겠습니다.

그러나 비트 플래그를 사용하는 예시를 보여주신 부분에서 unsigned char option1부터 시작해서 option8까지 선언하는 것이니

unsigned char items_flag까지 해서 총 9바이트로 오히려 손해를 부분이 아닌가요??

답변 1

1

안녕하세요? 질문&답변 도우미 Soobak 입니다.

 

'bool 플래그' 와, 'bit 플래그', 그리고 'bit 마스크' 에 대해서 아주 약간 혼동하고 계신 것 같습니다.

'bool 플래그' 는 bool boolFlags[8] = {fasle, }; 와 같은 형태이며,
'bit 플래그' 는 unsigned_char item_flag = 0; 과 같은 형태입니다.

const unsigned char opt0 = 1 << 0; , const unsigned char opt1 = 1 << 1; 과 같은 변수들은 'bit 마스크' 로서 비트 연산을 통해 특정 비트를 설정, 해제, 또는 확인 등을 하는 데에 사용됩니다.

 

즉, 8 개의 상태를 저장하기 위해서, bool 플래그는 8 개의 변수가, bit 플래그를 활용할 경우 1 개의 bit 플래그와 8 개의 bit 마스크가 필요하게 됩니다.

 

이때, '상태 저장' 의 관점에서 바라보면 8 개의 상태를 표현하기 위해서는 8 개의 bool 플래그 변수들이 모두 필요한 반면, bit 플래그를 활용한 경우에서는 8 개의 상태를 1 개의 bit 플래그 변수로 모두 표현할 수 있기 때문에 메모리 측면의 장점이 있는 것 입니다.

이는 특히, 네트워크나 파일 I/O 등에서 데이터 크기를 줄이는 데에 유용하게 사용됩니다.

 

bool 플래그의 사용과 bit 플래그의 사용에 대하여 크기 비교 부분을 확인하실 수 있도록 예시 코드를 첨부드려 봅니다.

#include <iostream>
#include <bitset>

int main() {
    // 비트 플래그 사용
    unsigned char bitFlags = 0;
    const unsigned char ITEM1 = 1 << 0;
    const unsigned char ITEM2 = 1 << 1;
    const unsigned char ITEM3 = 1 << 2;
    const unsigned char ITEM4 = 1 << 3;
    const unsigned char ITEM5 = 1 << 4;
    const unsigned char ITEM6 = 1 << 5;
    const unsigned char ITEM7 = 1 << 6;
    const unsigned char ITEM8 = 1 << 7;

    // bool 플래그 사용
    bool boolFlags[8] = {false};

    std::cout << "비트 플래그 크기: " << sizeof(bitFlags) << " 바이트\n";
    std::cout << "bool 플래그 배열 크기: " << sizeof(boolFlags) << " 바이트\n";

    // 비트 플래그 설정 및 출력
    bitFlags |= (ITEM1 | ITEM3 | ITEM5);
    std::cout << "비트 플래그 상태: " << std::bitset<8>(bitFlags) << "\n";

    // bool 플래그 설정 및 출력
    boolFlags[0] = true;
    boolFlags[2] = true;
    boolFlags[4] = true;
    std::cout << "bool 플래그 상태: ";
    for (int i = 0; i < 8; ++i) {
        std::cout << boolFlags[i];
    }
    std::cout << "\n";

    return 0;
}

: 출력 결과

비트 플래그 크기: 1 바이트
bool 플래그 배열 크기: 8 바이트
비트 플래그 상태: 00010101
bool 플래그 상태: 10101000

 

따라서, bit 플래그를 사용하면 bool 플래그를 사용하는 것에 비해서 메모리를 절약할 수 있습니다.

즉, 핵심은 items_flag 라는 비트 플래그 하나만을 사용하여, 1 바이트만으로 8 개의 아이템 상태를 저장하는 것의 효율성 입니다.

만약, bool 플래그를 사용한다면, 8 개의 bool 변수의 배열이 필요하게 됩니다.

 

또한, 메모리 측면 이외에도 비트 연산은 매우 빠르게 이루어지기 때문에, 연산의 효율성에서도 이점이 있습니다.

강진성님의 프로필 이미지
강진성
질문자

그럼 비트마스크는 메모리를 차지하지 않는다는 것알까요..??? const 한정자를 사용한 변수처럼 선언하는데 메모리를 갖지 않는 것일까요?

안녕하세요? 질문&답변 도우미 Soobak 입니다.

 

그렇지 않습니다. 'Bit 마스크' 도 메모리를 차지합니다.

다만, 핵심은

  • Bit 플래그

    • 하나의 변수(강의를 기준으로 unsigned_char item_flag)로 여러개의 상태를 표현할 수 있다는 점

    • 예를 들어 8 비트(1 바이트)변수 하나로 8 개의 개별 상태를 표현 가능

  • Bool 플래그

    • 8 개의 상태를 표현하려면 8 개의 개별 bool 변수가 모두 필요(8 바이트)

ITEM1 , ITEM2 와 같은 '비트 마스크' 역시 메모리를 차지하고, '비트 플래그' 를 표현하기 위해서 사용되지만,
'상태 표현' 에 초점을 맞춰보았을 때, 위와 같은 측면에서 Bit 플래그가 Bool 플래그에 비해 메모리에 대한 이점을 가지고 있다는 것입니다.

예를 들어, 8 개의 아이템에 대한 플레이어의 아이템 보유 상태 를 데이터로 전달할 때,
Bit 플래그의 경우 unsigned_char item_flag 라는 1 바이트의 변수만 전달하면 되지만,
Bool 플래그의 경우 8 개의 bool 변수를 모두 전달해주어야 하기 때문에 8 바이트가 필요하게 됩니다.

즉, 하나의 변수로 여러 개의 상태를 효율적으로 표현할 수 있어 메모리 사용을 줄일 수 있다는 것이 Bit 플래그의 이점입니다.

 

또한, 말씀해주신 내용과 연관 지어 추가적인 내용을 전달드려보면,
const 키워드와 함께 선언된 비트 마스크는 대부분 컴파일 타임에서 상수로 처리되기 때문에 컴파일러의 최적화 과정에서 메모리 사용이 최소화 되도록 최적화가 이루어집니다.

강진성님의 프로필 이미지
강진성

작성한 질문수

질문하기