한국어
C/C++

Bit fields(비트필드)

pjk 2014.05.24 12:14 조회 수 : 3986

Bit Field

비트필드는 각 구조체 구성요소를 비트 단위로 나눌 수 있다.

일반적인 구조체에서 구조체 구성요소는 C가 지원하는 데이터 형태로만 나누어지는데 비해 비트필드는 비트 단위로 구성요소를 나눌 수 있기 때문에 더욱더 세밀한 데이터 조정이 가능
비트필드는 구조 내에서 사용되기 때문에 먼저 구조 유형을 선언하여야 하는데, 다음과 같은 형태로 선언.

 struct bit_field {
         unsigned b1: 1;
         unsigned b2: 2;
         unsigned b3: 4;
         } x;

위를 보면 다른 구조의 정의와 같은데 구성요소의 이름 다음에 ':'를 붙이고 그 뒤에 비트의 크기를 지정하는 것이 다르다.
이때 이 구성요소는 위의 구조 내에서 딱 비트 크기 만큼의 비트 수만 차지하게 된다.
그리고 비트 필드를 사용하는 경우에 구성요소의 이름을 생략할 수 있는데, 이 경우 그 구성요소에 해당하는 비트들은 사용할 수 없게 된다(실제로 사용하지 않겠다는 의미가 된다).
또 비트 크기를 0으로 선언할 수도 있다. 이는 단어의 경계면으로 이동하여 그 다음 비트부터는 다른 바이트나 단어에 할당하라는 의미가 된다.

 struct move {
         unsigned x: 3;
         unsigned y: 3;
         unsigned z: 0;
         unsigned w: 5;
         } m;

 x는 처음 3비트를, y는 그 다음 3비트를 차지하게 되지만 z는 크기가 0이다.
따라서 z는 메모리를 차지하지 않으며 그 다음의 w를 y다음이 아닌 다음 워드(PC의 경우 짝수 바이트)에 할당하라는 의미가 된다.
따라서 m은 다음과 같은 구조를 갖게 된다.
일반적으로 하나의 비트필드의 크기는 단어의 크기를 초과할 수 없도록 되어 있으며, 단어 경계면에 걸쳐 존재할 수도 없게 되어 있다.
따라서 특정 비트필드가 단어 경계면에 존재하게 될 경우에는 위와 같이 다음 단어로 이동하는 것이 필요하게 된다.
그리고 비트 필드로 지정된 구성요소의 데이터 유형도 signed는 의미가 없기 때문에 unsigned int가 사용되며 비트 필드 형태의 배열은 사용할 수 없고 당연히 여기에 '&'연산자도 적용할 수 없다.

 #include <stdio.h>
 struct hangeul {
        unsigned int s: 1;        /*  부호  */
        unsigned int f: 5;        /*  초성  */
        unsigned int m: 5;        /*  중성  */
        unsigned int l: 5;        /*  종성  */
        };
  
main()
 {
   unsigned char c;
   unsigned char c2;
   struct hangeul h;
  
   while ((c = getchar()) != 255) {      /*  unsigned char라서 -1이 아닌 255  */
     h.s = ((c & 0x80) >> 7);
     if (h.s == 0) {
       printf("%c -> %dn",c,c);
       continue;
       }
  
     h.f = ((c & 0x7c) >> 2);
     h.m = ((c & 0x3) << 3);
     c2 = getchar();
     h.m |= ((c2 & 0xe0) >> 5);
     h.l = c2 & 0x1f;
  
     printf("%c%c -> %u, %u, %un",c,c2,h.f,h.m,h.l);
  
     }
 }