[C/C++] 10. 비트 연산자(2)

찰규

·

2026년 8월 1일 (30일 전)

지난 시간에는 비트 시프트 연산과 비트 논리 연산자, 그리고 #define 매크로의 기초 개념을 다루었다.

이번 시간에는 비트 연산자가 실무 및 게임 프로그래밍에서 실제로 어떻게 활용되는지 핵심적인 사용처인 상태 플래그(State Flag) 관리에 대해 알아본다.

1. 비트 자리를 이용한 상태 표현

32비트 정수형 변수(int) 하나는 총 32개의 0 또는 1(Bit)을 가질 수 있다. 이를 이용하면 변수 하나로 최대 32가지의 서로 다른 상태를 동시에 관리할 수 있다.

  • 비트 마스킹의 원리

    • 각 비트 자리에 고유한 의미(예: 배고픔, 목마름, 중독 등)를 부여한다.

    • 해당 비트가 1이면 상태 활성화(ON), 0이면 비활성화(OFF)를 나타낸다.

    • 각 상태의 값은 2의 거듭제곱(1,2,4,8,161, 2, 4, 8, 16 \dots) 형태를 띤다.

#define HUNGRY   0x001  // 1 (2^0)
#define THIRSTY  0x002  // 2 (2^1)
#define POISON   0x004  // 4 (2^2)
#define SLEEP    0x008  // 8 (2^3)

💡 16진수(0x) 표기법 활용

상태 값을 정의할 때는 10진수보다 16진수(0x) 를 주로 사용한다. 16진수는 비트 4개 단위로 깔끔하게 떨어지기 때문에 각 비트의 위치를 직관적으로 파악하고 관리하기 쉽다.

2. 비트 연산자 필수 3대 패턴

상태 플래그를 관리할 때 자주 쓰이는 추가, 검사, 제거의 3가지 연산 패턴은 반드시 숙지해야 한다.

① 상태 추가: |= (비트 OR)

특정 비트 자리를 1로 만들어 상태를 온(ON)시킨다. 다른 비트 자리에는 영향을 주지 않는다.

unsigned int iStatus = 0;

// iStatus에 THIRSTY(목마름) 상태 추가
iStatus |= THIRSTY; 

② 상태 검사: & (비트 AND)

특정 상태가 활성화되어 있는지 확인한다. 해당 비트 자리가 1이면 0이 아닌 참(True)의 값을 반환한다.

// iStatus에 THIRSTY(목마름) 상태가 있는지 검사
if (iStatus & THIRSTY) {
    // 목마름 상태일 때 처리할 로직
}

③ 상태 제거: &= ~ (비트 AND + NOT)

지우고자 하는 상태 비트만 0으로 뒤집은 뒤(~) AND 연산을 수행하여 안전하게 상태를 제거한다.

// iStatus에서 THIRSTY(목마름) 상태 제거
iStatus &= ~THIRSTY; 

⚠️ XOR(^) 연산으로 상태를 제거하면 안 되는 이유

XOR 연산은 비트가 다르면 1, 같으면 0을 반환하므로 이미 해당 상태가 켜져 있을 땐 꺼지지만, 상태가 꺼져 있을 때 적용하면 오히려 상태가 켜져 버리는 문제가 발생한다. 따라서 상태 제거 시에는 안전하게 &= ~ 패턴을 사용한다.

3. 실무 및 게임 개발에서의 활용

  • 게임 캐릭터의 버프/디버프 관리

    • 캐릭터가 현재 어떤 상태(비행, 무적, 독, 둔화 등)에 걸려 있는지 32비트 또는 64비트 변수 하나로 집약하여 빠르게 처리한다.
  • 복잡한 설정을 하나의 인자로 전달

    • 윈도우창 스타일 설정(최소화 버튼 유무, 닫기 버튼 유무, 창 크기 조절 여부 등)처럼 수많은 설정값을 하나의 변수에 묶어서 함수에 전달할 수 있다.

마무리하며

  • 32비트 정수형 변수의 각 비트 자리를 개별적인 상태 값으로 활용하여 최대 32가지의 상태를 동시에 효율적으로 관리할 수 있다.

  • 비트 OR 연산으로 특정 상태를 추가하고, 비트 AND와 반전 연산을 조합하여 특정 상태를 안전하게 제거하는 패턴은 게임 개발에서 빈번하게 사용된다.

  • 복잡한 매개변수를 하나로 통합 전달하거나 윈도우 스타일 설정 등 여러 상태 값을 하나의 변수에 담아 효율적인 시스템 설계가 가능하다.