한국어
C/C++
 

Bit fields(비트필드)

pjk 2014.05.24 12:14 조회 수 : 4018

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);
  
     }
 }


번호 제목 글쓴이 날짜 조회 수
공지 C Programming FAQs(한글번역 pdf문서) makersweb 2014.03.18 21182
19 배열과 포인터, 등가포인터 예제 makersweb 2019.01.16 15
18 싱글톤 객체생성 패턴에 대해서 file makersweb 2018.07.01 244
17 함수포인터와 typedef로의 선언 makersweb 2018.02.03 262
16 예제소스를 통해 리틀엔디안(Little endian)과 빅엔디안(Big endian)의 차이점 알아보기 pjk 2014.05.24 4706
15 switch와 if 중 어느 것이 더 빠른가 file makersweb 2017.01.31 1863
14 구조체 배열을 반환하는 함수를 반환하는 함수를 호출하여 구조체 멤버 배열 요소 접근하기 makersweb 2016.05.22 4381
13 c/c++문자열, 유니코드 관련 함수 makersweb 2015.07.09 4002
12 volatile이 정확히 어떤 의미를 가지는 건가요? pjk 2014.09.30 3407
11 HEX(16진수) to ASCII(아스키) 변환 코드 pjk 2014.08.24 13494
10 strcmp, wcscmp, _tcscmp pjk 2014.07.18 6779
9 클래스 멤버에 대한 액세스 제어 pjk 2014.06.27 3871
8 unsigned형의 모든 상수에는 접미사 ‘U’를 사용하여야 한다. file pjk 2014.05.24 33350
7 void형 포인터 pjk 2014.05.24 4579
6 함수 포인터의 배열 pjk 2014.05.24 5610
5 구조체 메모리 저장방식 #pragma pack file pjk 2014.05.24 4388
» Bit fields(비트필드) pjk 2014.05.24 4018
3 영어를 C언어로, 또는 C언어를 영어로 변환 해주는 cdecl makersweb 2014.03.19 3978
2 C언어 강좌-배열과 포인터 file makersweb 2014.03.10 4213
1 C코드 최적화 pjk 2014.02.10 4844