|

C 언어 비트 연산자는 언제 쓸까: AND, OR, XOR, shift 쉽게 정리

C 언어 비트 연산자 비트마스크 대표 이미지
비트 연산자는 숫자를 비트 단위의 스위치 묶음으로 다룰 때 힘을 발휘합니다.

C 언어 비트 연산자는 `&`, `|`, `^`, `<<`, `>>`처럼 숫자를 비트 단위로 다루는 연산자입니다. 처음에는 암호처럼 보이지만, 플래그와 마스크를 이해하면 쓰임새가 훨씬 분명해집니다.

핵심은 정수를 하나의 값이 아니라 여러 개의 0/1 스위치 묶음으로 보는 것입니다. 이 글은 C 연산자 기준 문서를 바탕으로 비트 연산자가 필요한 순간을 예제로 정리합니다.

C 언어 비트 연산자 요약 카드
AND, OR, XOR, shift는 각각 비트를 검사하고 켜고 뒤집고 이동하는 데 쓰입니다.

C 언어 비트 연산자를 먼저 한 줄로 정리하면

비트 연산자는 정수 값을 2진수 비트 단위로 다루는 연산자입니다. 일반 산술 연산이 숫자 전체를 계산한다면, 비트 연산은 숫자 안의 특정 자리만 검사하거나 바꿉니다.

unsigned int flags = 0;

flags = flags | 1u;   // 0번 비트 켜기
flags = flags & ~1u;  // 0번 비트 끄기

&는 특정 비트를 검사할 때 자주 쓴다

AND 연산 `&`는 양쪽 비트가 모두 1일 때만 1이 됩니다. 그래서 어떤 플래그가 켜져 있는지 확인할 때 자주 씁니다.

#define PERMISSION_READ  1u
#define PERMISSION_WRITE 2u

unsigned int permission = PERMISSION_READ | PERMISSION_WRITE;

if ((permission & PERMISSION_READ) != 0) {
    printf("read allowed\n");
}

비교 연산과 함께 쓸 때는 괄호를 분명히 넣는 편이 좋습니다. 연산자 우선순위를 암기하는 것보다 의도를 눈에 보이게 만드는 편이 안전합니다.

|는 비트를 켜거나 플래그를 합칠 때 쓴다

OR 연산 `|`는 둘 중 하나라도 1이면 결과가 1입니다. 그래서 여러 권한이나 옵션을 하나의 정수에 합칠 때 유용합니다.

unsigned int option = 0;

option |= PERMISSION_READ;
option |= PERMISSION_WRITE;

^는 다르면 1이 된다

XOR 연산 `^`는 두 비트가 다를 때 1이 됩니다. 특정 비트를 토글하거나, 두 값의 차이를 비트 단위로 확인할 때 쓰입니다.

unsigned int mask = 1u << 3;
flags = flags ^ mask;  // 3번 비트를 뒤집기

<<와 >>는 비트 위치를 이동한다

왼쪽 shift `<<`는 비트를 왼쪽으로 밀고, 오른쪽 shift `>>`는 오른쪽으로 밉니다. 특정 위치의 마스크를 만들 때 자주 사용합니다.

unsigned int bit3 = 1u << 3;  // 00001000
unsigned int bit5 = 1u << 5;  // 00100000

shift 연산은 부호 있는 정수, 너무 큰 이동 폭, overflow 같은 세부 규칙에서 주의가 필요합니다. 입문 단계에서는 비트마스크 용도라면 `unsigned` 계열을 쓰는 습관이 더 안전합니다.

비트 연산자는 언제 실제로 필요할까

  • 여러 boolean 옵션을 하나의 정수에 담을 때
  • 권한, 상태, 플래그를 빠르게 검사해야 할 때
  • 파일 포맷, 네트워크 패킷, 임베디드 레지스터처럼 비트 단위 의미가 정해져 있을 때
  • 알고리즘 문제에서 부분집합이나 마스크 상태를 표현할 때

실수하기 쉬운 부분

  • 논리 AND `&&`와 비트 AND `&`를 헷갈린다
  • 비교 연산과 섞으면서 괄호를 생략한다
  • signed 정수 shift의 세부 동작을 단순 산술로만 생각한다
  • 비트마스크 이름 없이 숫자 리터럴만 써서 의미를 잃는다

정리

C 언어 비트 연산자는 숫자 전체가 아니라 숫자 안의 각 비트를 직접 다루기 위한 도구입니다. 플래그와 마스크를 이해하면 `&`, `|`, `^`, `<<`, `>>`의 역할이 훨씬 자연스럽게 보입니다.

C 기초 흐름은 C 언어 define const 차이, C 언어 포인터와 배열 차이, C 언어 enum은 왜 쓸까와 함께 보면 좋습니다. 외부 기준은 cppreference – Bitwise logic, cppreference – Shift operators, cppreference – Operator precedence를 확인했습니다.

함께보면 좋은 글