본문 바로가기
  • 오늘도 신나게
코딩을 합시다/최대한 쉽게 설명한 C 언어

초등학생도 이해하는 C 언어 - 비트연산자

by 앵그리선반장 2020. 5. 22.

사람들이하는 계산방식과 다르게 컴퓨터가 하는 연산에는 비트연산 이라는 것이 있어요.

비트 연산을 하기 위해서는 데이터의 저장 형태를 이해 해야합니다.

일반적으로 int 형으로 선언된 변수는 4byte 크기 입니다.

1byte 는 8bit 이므로 int 형은 32개의 bit 가 연속으로 이어진 형태 입니다.

만약 64 라는 데이터를 int 형의 변수에 저장 한다면 , 실제로 저장된 데이터는 아래와같은 형태 입니다.

00000000000000000000000001000000

이것을 보기 쉽게 바이트 단위로 나눠서 표시하면

맨 우측부터 비트자릿수 0 부터 시작 됩니다.

위에서 저장한 64 라는 정수는 실제로 6번 비트만 1인 형태로 저장됨을 알 수 있습니다.

이것을 hex 값으로 표시하면,

0x00000040 이 됩니다.

hex 값은 0~F (123456789ABCDEF) 까지 16개의 숫자로 이루어진 진수법이며, 16개는 4비트로 표현 할 수 있습니다.

그래서 위 4바이트를 hex 값으로 표시할때는 4개의 비트에 하나의 16진수 숫자로 표시할 수 있지요.

0000 0000    0000 0000    0000 0000    0100 0000

   0      0         0     0         0      0        4      0 

이게 비트연산이랑 무슨 상관이냐고요?

비트 연산은 이처럼 숫자를 비트로 저장된 상태에서 이루어지는 연산 입니다.

예를 들어 만약 위 값에서 유일하게 1 인 6번째 비트 값을 오른쪽으로 한칸 이동 했다고 생각해 보세요.

그럼 모든 데이터비트가 0 이고, 5만 1인 데이터의 값은 무엇일까요?

비트로 모두 표현하면

0000 0000    0000 0000    0000 0000    0010 0000

Hex 값으로 하면 0x00000020 이 됩니다.

이 값은 정수로 32에 해당 하지요.

비트를 옆으로 이동 시키는 것을 쉬프트 라고 하며, 비트 연산으로 이 값이 절반으로 떨어진 것을 알 수 있어요.

반대로 좌측으로 이동했다면 어떻게 될까요?

Hex 값으로 0x00000080 이 되고, 이 값은 정수로 128 이 됩니다.

단순히 숫자를 빼거나 더한것과는 다른 형태 임을 알 수 있지요.

이처럼 비트의 형태를 변경 하는 연산자를 비트연산자라 하고,

c 에서는 다음과 같은 비트연산을 지원 합니다.

연산자 기능
& 비트 연산 AND ( 두 비트가 모두 1 이면 1, 아니면 0 )
| 비트 연산 OR ( 두 비트중 하나라도 1 이면 1 )
^ 비트 연산 XOR ( 두 비트가 다르면 1, 같으면 0 )
~ 비트연산 NOT ( 비트의 상태를 반전 )
<< 비트연산 Shift ( 비트를 좌측으로 이동 한다.)
>> 비트연산 Shift ( 비트를 우측으로 이동 한다. )

여기서 &와 && 를 착각 하거나 | 와 || 를 착각 하시는 경우가 있는데요.

&&와 || 는 논리 연산자며, 비트연산자가 아님을 기억 하시기 바랍니다.

이제 예제를 보면서 하나씩 연산자의 동작을 알아보겠습니다.

#include <stdio.h>
int main(void)
{

	int a,b,c;
	a = 0x01;
	b = 0x03;
	c = 0x00;

	c = a&b;
	
	printf("0x%08x & 0x%08x = 0x%08x \n",a,b,c);

	return 0;
}

이 연산은 다음과 같은 연산을 합니다.

and 연산

1과 3 은 0번과 1번 비트만으로 표시되며, 두 비트는 모두 0번 비트만 1 입니다.

따라서 &(AND) 연산을 하면 둘다 1 인 0 번 비트만 1 로 출력 됩니다.

| (OR) 은 어떨까요?

둘 중 하나만 1 이면 1 이 출력 되므로,

출력 값은 0번 비트와 1 번 비트가 모두 1 인 정수 3이 됩니다.

여기서 비트연산을 잘 하기 위해서는 다음 표를 머리속에 그려두시는게 좋아요.

16진수와 Binary 형태를 머리속에 딱 넣고 있으면, 비트 연산은 매우 쉬워 집니다.

|  (OR) , ^ (XOR) 연산은 AND 를 이해 했다면 매우 쉽습니다.

개념적으로 AND, OR, XOR 만 이해 하고 있으면 되거든요.

그 개념을 표로 그려보면,

입니다.

디지털논리회로를 공부하면 알게 되지요.

아, 참고로 임베디드를 하고자 마음을 먹었다면 디지털논리회로를 무조건 깊게 공부하시기 바랍니다.

카운터를 설계할 수 있을 정도까지는 공부하시는게 좋아요. 많은 도움이 될겁니다.

이제 XOR 까지 했으니 ~ 을 알아볼 차례 입니다.

이것은 NOT 입니다.

위의 표에서 먼저 보여드린것과 같이 비트를 반전 하지요.

예제를 보겠습니다.

#include  <stdio.h>

int main(void)
{
    int a = 0x5555;

    a = ~a;
    printf("a = 0x%08x \n",a);
    
    a = ~a;
    printf("a = 0x%08x \n",a);
}

이 코드를 실행 하면,

a = 0xffffaaaa 
a = 0x00005555 

위와 같이 출력 됩니다.

먼저 숫자 5 는 비트 값으로 0101 이고 이것을 반전시키면 1010 이 되어 Hex 값은 0xA 가 됩니다.

그런데 앞의 FFFF 는 뭘까요?

네 맞아여 4바이트 정수 (int) 로 선언되었기 때문에 0x5555 는 실제로 0x00005555 가 됩니다.

따라서 이것을 반전 시키면 0 응 비트 값으로 0000 이므로 1111 이 되어 모두 f 가 됩니다.

그다음 코드에서 다시 반전 시켜 원래대로 다시 출력 되네요.

여기서 %x  는 16진수 값을 출력 하기위한 치환자 이고요, 앞에 붙은 08 은 8자리씩 출력 하라는 뜻입니다.

다음은 쉬프트 연산자 입니다.

 

계속..

댓글