1. 비트 연산자의 종류

     

    & : 비트 AND
     | : 비트 OR
     ^ : 비트 XOR
     ~ : 비트 NOT
     << : 비트를 왼쪽으로 시프트
     >> : 비트를 오른쪽으로 시프트

     비트연산자는 비트로 옵션을 설정할 때 주로 사용. 이런방식을 FLAG라고 한다.

     

    2. AND / OR / XOR

     

    #include <stdio.h>

    void main() {
         unsigned char num1 = 1; // 0000 0001
         unsigned char num2 = 3; // 0000 0011

        

     printf("AND : %d\n", num1 & num2); // 0000 0001 : 01과 11을 AND 하면 01이 된다.
     printf("OR : %d\n", num1 | num2);  // 0000 0011 : 01과 11을 OR하면 11이 된다.
     printf("XOR : %d\n", num1 ^ num2); // 0000 0010 : 01과 11을 XOR하면 10이 된다

    }

     

    AND 는 두 비트가 모두 1 일때 1을 반환하고, 하나라도 0 일때는 0을 반환한다.

    ex ) ( 1 , 1 ) = 1    ( 0, 1 ) = 0    ( 1, 0 ) = 0    ( 0 , 0 ) = 0

     

    OR 는 두 비트가 어느것이라도 1일 때 1을 반환하고, 모두 0일때만 0을 반환하게 된다.

    ex) ( 1 , 1 ) = 1    ( 0 , 1 ) = 1    ( 1 , 0 ) = 1    ( 0 , 0 ) = 0

     

    XOR은 두 비트중 하나만 1이여만 1을 반환한다, 모두 0이거나 모두 1일때는 0을 반환하게 된다.

    ex) ( 1 , 1 ) = 0    ( 0 , 1 ) = 1    ( 1 , 0 ) = 1    ( 0 , 0 ) = 0

     

    3. NOT

    #include <stdio.h>

    void main() {
     unsigned char num1 = 162; // 1010 0010
     unsigned char num2;

     

         num2 = ~num1;

         printf("%d\n", num2);  //0101 1101

    }

     

    NOT은 비트를 뒤집는다, 혹은 비트 반전이라도 이야기한다. 0은 모두 1로 바꾸고 1은 모두 0으로 바꾼다.

     

    4. SHIFT

    #include <stdio.h>

    void main() {
         unsigned char num1 = 3;  // 3: 0000 0011
         unsigned char num2 = 24; // 24: 0001 1000

         printf("%u\n", num1 << 3); // 24: 0001 1000 : num1의 비트 값을 왼쪽으로 3번이동
         printf("%u\n", num2 >> 2); // 6: 0000 0110 : num2의 비트 값을 오른쪽으로 2번 이동
    }

     

     

    SHIFT는 비트를 왼쪽(<<), 오른쪽(>>)으로 이동한다.

    SHIFT 연산자를 이용하면 왼쪽으로 한번이동할때마다 2의 제곱수만큼 곱해진다.

    그렇기에 시프트 연산자는 2의 거듭제곱인 숫자를 빠르게 구할 때 유용하다.

    ex) num1 << 3        : 3번 왼쪽으로 이동했으니 원래 있던 수에서 2의 3제곱 만큼 곱해진다. 3 * 8 = 24

     

    오른쪽으로 이동하면 2의 제곱수만큼 나눠진다.

    ex) num2 >> 2        : 2번 오른쪽으로 이동했으니 원래 있던 수에서 2의 2제곱만큼 나눠진다. 24 / 4 = 6

     

    (    SHIFT 연산을 할때는 부호가 바뀌거나 자신이 의도치 않은 값이 나올 수도 있다.    )

     

    SHIFT 연산자가 부호없는 자료형의 비트 첫자리나 마지막 자리가 크기 밖으로 이동하면 그 비트는 사라진다.

     

    부호있는 자료형라면 기본적으로 맨 앞 비트 (0000 0000)가 부호를 결정하는 비트가 된다.

     

    만약 첫자리가 부호 비트가 음수, -125 (1000 0011)일 때 << 5 연산을 하면 어떻게 될까?

    뒤 두자리 비트는 오른쪽으로 움직여 사라지고 부호 비트는 5자리 뒤로 이동하면서 그 자리를 1로 채우게 된다.

    1000 0011 -> 1100 0001 -> 1110 0000 -> 1111 0000 -> 1111 1000 -> 1111 1100

    그러므로 -4(1111 1100)이된다.

     

     

    그러면 부호 비트가 0인 양수, 67(0100 0011) >> 5 연산을 하면 어떻게 될까?

    뒤 두자리 비트는 오른쪽으로 움직여 사라지고 부호 비트는 5자리 뒤로 이동하면서 그 자리르 0 으로 채우게 된다.

    0100 0011 -> 0010 0001 -> 00001 0000 -> 0000 1000 -> 0000 0100 -> 0000 0010

    그러므로 2(0000 0010)가 된다.

     

     

    부호 있는 자료형에서 << 2 연산을 해보면 어떻게 될까?

    113(0111 0001), -15(1111 0001)

    113 >> 2

     

    0111 0001 -> 1110 0010 -> 1100 0100

    왼쪽으로 움직인 비트들은 사라지고,

    부호비트는 1로 바뀌고 음수로 읽혀지게 되어 -60으로 읽혀진다.

     

    -15 >> 2

    1111 0001 -> 1110 0010 -> 1100 0100

    왼쪽으로 움직인 비트들은 사라지고,

    부호비트는 같고 -60으로 읽혀진다.

     

     

     

     

     

    5. 비트 연산자로 플래그 처리하기

     

    비트로 적은 공간을 사용하여 빠른 속도를 내게 해준다.

    비트가 1이면 ON, 0이면 OFF를 나타내고, 1바이트당 총 8개의 상태를 저장할 수 있다.

     

    5-1 . 특정 비트 키기

    FLAG |= (?)

    ex)  flag |= 1; // 0000 0001 비트 OR로 여덟번째 비트를 킨다.

           flag |= 2; // 0000 0010 비트 OR로 일곱번째 비트를 킨다.

     

    5-2. 특정 비트 확인하기

    if문 안에 사용하며 비트가 있으면 1을 반환하고 없으면 0을 반환한다

     

    FLAG &= (?)

    ex) 현재 FLAG는 (0000 0011)

    flag &= 1 // 0000 0001 비트가 켜져있는지 확인한다.(1 반환)

    flag &= 4 // 0000 0100 비트가 켜져있는지 확인한다.(0 반환)

     

    5-3. 특정 비트 끄기

    FLAG &= ~(?)

    ex) 현재 FLAG는 (0000 0011)

    flag &= ~2 // 0000 0011 & 1111 1101 = 0000 0001 이되므로 2의 비트가 꺼지게된다.

     

    5-4. 특정 비트가 켜져있다면 끄고, 꺼져있다면 키기

    FLAG ^= (?)

    ex) 현재 FLAG는 (0000 0001)

    flag ^= 1 // 0000 0001 ^ 0000 0001 = 0000 0000; 

    flag ^= 8 // 0000 0000 ^ 0000 1000 = 0000 1000;

    'C (예제, 문제)' 카테고리의 다른 글

    0321  (0) 2017.03.21
    0319  (0) 2017.03.19
    0318-1  (0) 2017.03.18
    소코반  (0) 2017.03.14
    [이중 for문]별 찍기  (0) 2017.03.11
    Posted by Config