지금까지 자료형은 바이트 단위로 구분하였다.
비트 연산자는 비트 단위로 연산하는 연산자이다.
종류:
& - 비트AND
| - 비트OR
^ - 비트XOR
~ - 비트NOT
<< - 비트를 왼쪽으로 쉬프트
'>> - 비트를 오른쪽으로 쉬프트
&= - 비트AND 연산 후 할당
!= - 비트OR 연산 후 할당
^= - 비트XOR 연산 후 할당
<<= - 비트를 왼쪽으로 시프트한 후 할당
'>>= - 비트를 오른쪽으로 시프트한 후 할당
비트연산자는 비트로 옵션을 설정할 때 주로 사용하며 저장 공간을 아낄 수 있는 장점이 있다.
이런 방식을 플래그(flag)라고 부른다.
비트 연산자는 모든 연산을 2진수로 처리한다.
int main()
{
unsigned char num1 = 1;
unsigned char num2 = 3;
printf("%d\n", num1 & num2);
printf("%d\n", num1 | num2);
printf("%d\n", num1 ^ num2);
}
>>> 1
>>> 3
>>> 2
unsigned char 자료형에 1을 할당했을 때 비트로 표현하면 0000 0001이고 3은 0000 0011 이다.
비트 연산은 두 값을 비트 단위로 나열한 뒤 각 자릿수를 비트 연산자로 연산한다.
각 자릿수의 연산은 독립적이고 다른 자릿수에 영향을 주지 않으며 비트 단위로 연산한 각 자릿수를 모두 모으면 최종결과가 된다
0000 0001
0000 0011
&
0000 0001 = 1
0000 0001
0000 0011
|
0000 0011 = 3
0000 0001
0000 0011
^
0000 0010 = 2
unsigned char num1 = 162;
unsigned char num2;
num2 = ~num1;
printf("%u\n", num2);
>>> 93
비트NOT(~) 연산자는 '비트의 반전'이라 할 수 있으며 0011 0101이라는 2진수를 반전(~)시키면 1100 1010이 된다.
unsigned char는 부호없는 정수이며 1바이트 크기이다. 비트 연산으로 인해 부호 비트가 영향을 받지 않도록 부호없는 자료형을 사용한다.
시프트 연산자는 >>, <<이며
A >> B 는 'A의 2진수를 >>방향으로 B만큼 이동한다' 이다.
int main()
{
unsigned char num1 = 6;
unsigned char num2 = 24;
printf("%d\n", num1 >> 2 );
printf("%d\n", num2 << 1 );
}
>>> 1
>>> 48
위와같이 num1 이 6일때 2진수는 0000 0110 이다. 이를 "num1 >> 2" 하면 2진수를 오른쪽 방향으로 2칸 간다는 의미로 0000 0001 이 된다. 그러므로 결과는 1이다.
num1 >> 2는 num1 / 2^2 이고
num2 << 1은 num2 * 2^1 이다.
사칙연산 +,-,,/ 와 +=, -=. =. /= 처럼
비트 연산자도 &=, |=, ^=, !=, <<=, >>= 이 있다.
int main()
{
unsigned char num1 = 4; // 0000 0100
num1 &= 5; // 0000 0101
printf("%d\n", num1);
}
>>> 4 // 0000 0100
위 처럼 num1 &= 5가 있으면 num1 = num1 & 5랑 같다.
비트 연산 후 할당은 특히 플래그를 켜거나 끌 때 유용하게 활용된다.