비트 연산자는 정수형의 개별 비트를 조작합니다:
& — 비트 AND| — 비트 OR^ — 비트 배타적 OR~ — 비트 NOT<< — 왼쪽 시프트>> — 오른쪽 시프트특징:
int, unsigned int, 등)에서만 작동합니다.signed)의 경우 오른쪽 시프트(>>)시 산술 시프트 또는 논리 시프트가 발생할 수 있으며, 이는 컴파일러에 따라 다릅니다.unsigned 타입을 선택하여 부호 확장을 피하는 것이 좋습니다.예:
unsigned int flags = 0; flags |= 0x1; // 0 번째 비트 설정 flags &= ~0x2; // 1 번째 비트 리셋 if ((flags & 0x4) != 0) { /* ... */ } // 2 번째 비트 확인
signed int와unsigned int의 오른쪽 시프트(>>)의 차이는 무엇인가요?
자주 잘못된 답변: 오른쪽 시프트는 항상 왼쪽에 0을 삽입한다고 여깁니다, 부호에 관계없이.
올바른 답변:
unsigned int의 경우 오른쪽 시프트(>>)는 항상 0을 삽입합니다. signed int의 경우 삽입되는 것은 부호(음수가 될 경우 1) 또는 0이며, 이는 컴파일러의 구현(아키텍처 및 C 표준의 규칙)에 따라 달라집니다.
예:
signed int a = -8; unsigned int b = (unsigned int)a; printf("%d ", a >> 1); printf("%u ", b >> 1);
첫 번째 경우 결과는 컴파일러에 따라 다르며, 두 번째 경우는 항상 0으로의 논리적 시프트가 됩니다.
이야기
프로토콜 처리 코드에서 신호 플래그가 char 타입에 저장되었습니다. 프로그래머는 8비트 시프트(flag << 8)를 적용했으며, 이는 오버플로와 타입 승격 규칙으로 인해 모든 데이터가 손실되어 결과가 항상 0이 되었습니다.
이야기
네트워크 프로토콜에서 데이터 읽기 (big-endian). 바이트를 결합하기 위해 비트 연산을 사용할 때 unsigned로 변환하지 않아 구조체의 필드를 읽을 때 가끔 예기치 않은 음수 값이 발생했습니다.
이야기
~ (비트 NOT)를 사용하여 int 타입의 비트를 리셋할 때 (예: ~0x80), 이는 0x7F로 해석되지만 실제로는 음수 -129가 되어 후속 계산 및 논리적 검증 시 오류를 발생시켰습니다.