56.2 비트 필드와 공용체를 함께 사용하기
보통 사람이 코드에서 값을 지정할 때는 비트 필드를 사용하지만 CPU나 칩에 값을 설정할 때는 모든 비트를 묶어서 한꺼번에 저장합니다. 이번에는 비트 필드의 값을 한꺼번에 사용할 수 있도록 비트 필드와 공용체를 함께 사용해보겠습니다.
예제를 보기 전에 지금까지 공부한 구조체와 공용체를 이용해서 그림 56‑3을 코드로 만들어보고, 예제와 비교해보세요.
struct_union_bit_field.c
#include <stdio.h> struct Flags { union { // 익명 공용체 struct { // 익명 구조체 unsigned short a : 3; // a는 3비트 크기 unsigned short b : 2; // b는 2비트 크기 unsigned short c : 7; // c는 7비트 크기 unsigned short d : 4; // d는 4비트 크기 }; // 합계 16비트 unsigned short e; // 2바이트(16비트) }; }; int main() { struct Flags f1 = { 0, }; // 모든 멤버를 0으로 초기화 f1.a = 4; // 4: 0000 0100 f1.b = 2; // 2: 0000 0010 f1.c = 80; // 80: 0101 0000 f1.d = 15; // 15: 0000 1111 printf("%u\n", f1.e); // 64020: 1111 1010000 10 100 return 0; }
실행 결과
64020
먼저 비트 필드로 사용할 멤버는 익명 구조체로 감싸줍니다. 그리고 비트 필드의 값을 한꺼번에 접근할 수 있도록 unsigned short형 멤버를 선언하고 익명 공용체로 감싸줍니다. 여기서는 2바이트(16비트) 크기의 unsigned short에 정확히 맞추기 위해 비트 수를 3, 2, 7, 4로 지정했습니다.
struct Flags { union { // 익명 공용체 struct { // 익명 구조체 unsigned short a : 3; // a는 3비트 크기 unsigned short b : 2; // b는 2비트 크기 unsigned short c : 7; // c는 7비트 크기 unsigned short d : 4; // d는 4비트 크기 }; // 합계 16비트 unsigned short e; // 2바이트(16비트) }; };
이제 비트 필드에 값을 할당합니다. 여기서는 각 비트 수에 맞게 값을 할당했습니다.
f1.a = 4; // 4: 0000 0100 f1.b = 2; // 2: 0000 0010 f1.c = 80; // 80: 0101 0000 f1.d = 15; // 15: 0000 1111
공용체로 감싸준 멤버 e를 printf로 출력해보면 64020이 나옵니다. 즉, 비트 필드에 할당한 비트들을 차례대로 연결하면 1111 1010000 10 100이 되므로 10진수로 표현했을 때 64020이 됩니다.
printf("%u\n", f1.e); // 64020: 1111 1010000 10 100
지금까지 비트 필드에 대해 배웠는데 비트 단위로 값을 다루다보니 눈에 잘 들어오지 않았습니다. 비트 필드는 쓸 일이 많지 않으므로 이런 기능이 있다 정도로만 알아두면 됩니다.