C언어의 비트 연산을 배우고 나서 좀 헷갈려서 정리하려 합니다.
비트 연산이란, 변수 안에 있는 수를 2진수로 변환 후 각 자릿수에 대해 연산자를 이용해 연산하는 것이다.
비트 연산자에는 & (and) , | (or) , ^ (xor) , ~(not) ,<<,>>(왼쪽,오른쪽으로 비트 이동)이 있다.
and는 둘다 1일때 1출력
or는 하나라도 1일때 1출력
xor는 or에서 둘다 1일때 0을 출력
not은 1이면 0출력 0이면 1출력 한다.
그럼 이제 응용해보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#include <stdio.h>
int main()
{
char a=4,b=15,c=127,d,e,j=22;
unsigned char f,g,h;
unsigned char i=0xbf;
printf("%d %d %d\n",a,b,c);
printf("%d %d %d\n",a<<1,a>>2,a>>3);
printf("%d %d %d %d\n",c<<1,c<<2,d=c<<2,f=c<<2);
printf("%d %d %d\n",sizeof(c),sizeof(c<<1),sizeof(c<<2));
printf("%d %d %d %d\n",a&j,a|j,a^j,~a);
printf("%x %x %x",b&(i>>4),b&i,i);
return 0;
}
|
cs |
실행결과
4 15 127
8 1 0
254 508 -4 252
1 4 4
4 22 18 -5
b f bf
첫째줄은 당연히 4, 15, 127이 출력된다.
두번째 줄을 보자. 두번째 줄의 출력결과는 8, 1, 0 이다.
각 수를 2진수로 변환해서 생각해보자.
4를 이진수로 변환하면 0000 0100
15를 이진수로 변환하면 0000 1111
127을 이진수로 변환하면 0111 1111 이다.
0000 0100 을 왼쪽으로 1비트씩 움직이면(<<1) 0000 1000 이 된다.
이 때 제일 왼쪽 0에서는 끌어올게 없기 때문에 0을 끌어온다. 그러므로 0000 1000 이 나온다.
마찬가지로 (>>2)를 실행하면 0000 0001이 되기 때문에 1이 출력된다.
그렇다면 여기서 한번더 오른쪽으로 가면 어떻게될까? 답은 0000 0000이다. 제일 왼쪽에 있던 1은 사라진다.
세번째 줄을 보자. 세번째 줄의 실행 결과는 254, 508, -4, 252 가 나온다.
c는 0111 1111이다. 이것을 왼쪽으로 1칸 옮기면 1111 1111이 되므로 -1이 아닐까? 하지만 254가 나온다.
c 변수 그 자체는 char 형태로 존재할 수 없는 것이다. 네번째 줄 두번째 수는 c<<1 의 크기가 4바이트라고 알려준다.
마찬가지로 c<<2를 실행하면 508이 나온다. 자료형 자체가 바뀌었기 때문이다.
그렇다면 세번째줄 세번째 수는 왜 -4가 나올까? 간단하다. signed char 자료형에 비트를 가져다 박았기(?) 때문이다.
c<<2 를 char 형태 안에서 표현하면 1111 1100 이 나온다. 이것은 -4를 나타낸다.
하지만 세번째줄 네번째 수는 252를 가르킨다. 왜냐하면, unsigned char 자료형에 비트를 붙여넣었기 때문이다.
맨 앞자리 비트가 부호비트가 아니라 일반 숫자비트 이므로 252가 나온다.
네번째 줄은 각 자료형의 크기를 나타낸 것이다.
char는 1바이트, c<<1 과 c<<2 는 4바이트로 늘어난 모습이다.
다섯번째 줄에선 a랑 j의 연산이다. 출력은 4, 22, 18, -5 가 나온다.
a는 0000 0100 이고 j는 0001 0110 이다.
각 자리의 계산은 녹색 네모를 보자. 녹색 네모에서의 계산 결과가 아래에 적힌다.
즉, 순서대로 4, 22, 18 이 출력된다. NOT 계산은 각 비트를 반전시켜주면 된다.
NOT 계산의 예) 0110 -> 1001
마지막으로 이것을 응용해 16진수의 각 자릿수를 분리하는 것을 볼 수 있다.
16진수 bf는 2진수로 1011 1111 이다. 10진수 15는 2진수로 0000 1111 이다.
AND 연산자를 쓰면 0은 버려지고 1만 살리므로 각 자릿수를 분리할 수 있다.
그렇게 출력은 f,b 가 나온다. 마지막으로 원본이랑 대조하기 위해서 i를 출력시켰다.
'프로그래밍 언어 > C C++' 카테고리의 다른 글
줄넘김 문자 endl , \n 차이 (0) | 2021.03.24 |
---|---|
gcc 를 이용해 c언어 간단히 컴파일하기 (0) | 2021.03.23 |
main 함수에 입력 변수 설정하기 (0) | 2021.03.03 |
C언어로 계산식을 이용한 원주율(파이) 구하기 (0) | 2019.06.03 |
C언어의 입력,출력 및 자료형 정리 (0) | 2019.02.10 |