본문 바로가기

Programming/C

구조체 비트 필드 structure bit field

반응형


"구조체(structure)의 비트 필드(bit field)" 는 구조체의 정수 타입의 멤버 변수를 

비트 단위로 쪼개서 사용할 수 있게끔 해주는 방법이다.


사용법 :

struct 구조체 이름 {
     정수형type 변수명 : 비트수
}

정수형type : (unsigned, signed)char, short, int, long 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
  
struct normal {
        unsigned char ch1;
        unsigned char ch2;
};
struct bit_field {
        unsigned char ch1 : 3;
        unsigned char ch2 : 2;
};
 
int main()
{
        printf("normal size : %d, bit_field size : %d \n",
                 sizeof(struct normal), sizeof(struct bit_field));
 
        return 0;
}
cs

실행 결과 : normal size : 2, bit_field size : 1


bit_field 구조체는 char타입 1byte 만 메모리에 할당하고 

ch1이 3bit, ch2가 2bit를 사용한다.


그림으로 그려보면 bit_field 구조체는 다음과 같이 된다.






1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
  
struct bit_field {
        unsigned int int1 : 3;
        unsigned char ch1 : 2;
};
 
int main()
{
        printf("bit_field size : %d \n",
                 sizeof(struct bit_field));
 
        return 0;
}
cs
a

실행 결과 : bit_field_size: 4

만약 정수형 data type이 섞여 있다면,  구조체는 위와 같이

가장 큰 타입의 크기를 따르게 된다. (비록 5bit만 쓸지라도 char가 아닌, unsigned int로 크기를 할당함)



1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
  
struct bit_field {
        unsigned char ch1 : 7;
        unsigned char ch2 : 2;
};
 
int main()
{
        printf("bit_field size : %d \n",
                 sizeof(struct bit_field));
 
        return 0;
}
cs

실행 결과 : bit_field_size: 2

만약,  사용할 bit의 합(위 경우 total 9bit) 이 할당할 data type (위 경우 unsigned char, 8bit)보다 크다면, 

할당할 data type크기 만큼 더 증가하여 할당한다. 



멤버가 unsigned 가 아닌, signed의 경우 MSB는?

할당된 bit중,  그 최상위 bit가 MSB 역할을 한다.


아래는 이해를 돕기 위한 코드.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
  
struct bit_field {
        int int1 : 3;
};
 
int main()
{
        struct bit_field test;
        int i;
 
        for (test.int1 = 0, i = 0; i < 10; i++) {
                printf("[i:%d] int1 : %d \n", i, test.int1);
                test.int1++;
        }
 
        return 0;
}
 
cs


실행 결과 :


i

 멤버 int1 값

십진수참고
00000 
10011 
20102 
30113 
4100-4011(보수) + 1 --> 100 = 4 결과에 마이너스
5101-3010(보수) + 1 --> 011 = 3 결과에 마이너스
6110-2001(보수) + 1 --> 010 = 2 결과에 마이너스
7111-1000(보수) + 1 --> 001 = 1 결과에 마이너스
80000

 1000 --> 000

90011 



그럼 구조체 비트 필드를 왜 쓰는 것일까?

1. 임베디드 시스템 환경에서는 메모리 사이즈가 넉넉하지 않은 경우가 많다. 

   구조체 비트필드를 활용하면 메모리 사이즈를 줄일 수 있다. 

   (ex, true / false 를 위한 boolean flag로 1bit만 할애할 수 있다.)


2. 실수로 값을 잘못 assign 해 준 것을 warning message로 쉽게 알 수 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
  
struct bit_field { 
        int int1 : 3
};
 
int main()
{
        struct bit_field test;
        int i;
 
        test.int1 = 10;
 
        return 0;
}
 
cs

위 코드를 실행하면

위와 같은 에러를 띄어준다. (the value exceeds its type size 와 같은 warning이 나올 수도 있음)


반응형