C 비트 필드


프로그램 구조에 스위치가 여러 개 포함된 경우 다음과 같이 TRUE/FALSE 변수만 있습니다.

struct{  unsigned int widthValidated;  unsigned int heightValidated;} status;

이 구조에는 8바이트의 메모리 공간이 필요하지만 실제로 각 변수에는 0 또는 1만 저장됩니다. 이 경우 C 언어는 메모리 공간을 활용하는 더 나은 방법을 제공합니다. 구조 내에서 이러한 변수를 사용하는 경우 변수의 너비를 정의하여 컴파일러에 해당 바이트만 사용할 것임을 알릴 수 있습니다. 예를 들어 위 구조는 다음과 같이 다시 작성할 수 있습니다.

struct{  unsigned int widthValidated : 1;  unsigned int heightValidated : 1;} status;

이제 위 구조에서 상태 변수는 4바이트의 메모리 공간을 차지하지만 값을 저장하는 데는 2비트만 사용됩니다. 32개의 변수를 사용하는 경우 각 변수의 너비는 1비트이므로 상태 구조는 4바이트를 사용하지만 변수를 하나 더 사용하자마자 33개의 변수를 사용하는 경우 저장하기 위해 다음 메모리 섹션을 할당합니다. 이때 33번째 변수인 8바이트가 사용됩니다. 이 개념을 이해하기 위해 다음 예를 살펴보겠습니다.

#include <stdio.h>#include <string.h>/* 定义简单的结构 */struct{  unsigned int widthValidated;  unsigned int heightValidated;} status1;/* 定义位域结构 */struct{  unsigned int widthValidated : 1;  unsigned int heightValidated : 1;} status2; int main( ){
   printf( "Memory size occupied by status1 : %d\n", sizeof(status1));
   printf( "Memory size occupied by status2 : %d\n", sizeof(status2));   return 0;}

위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.

Memory size occupied by status1 : 8Memory size occupied by status2 : 4

Bitfield 선언

구조체 내부에서 비트필드를 선언하는 방법은 다음과 같습니다.

struct{
  type [member_name] : width ;};

다음은 비트 필드의 변수 요소에 대한 설명입니다.

Element Description
type정수 유형에 따라 비트 필드의 값이 해석되는 방식이 결정됩니다. 유형은 정수, 부호 있는 정수 또는 부호 없는 정수일 수 있습니다.
member_name비트 필드의 이름입니다.
width비트 필드의 비트 수입니다. 너비는 지정된 유형의 비트 너비보다 작거나 같아야 합니다.

미리 정의된 너비를 가진 변수를 비트 필드라고 합니다. 비트필드는 1비트 이상을 저장할 수 있습니다. 예를 들어 0부터 7까지의 값을 저장하는 변수가 필요한 경우 다음과 같이 3비트 너비의 비트필드를 정의할 수 있습니다.

struct{  unsigned int age : 3;} Age;

위의 구조 정의는 다음과 같이 지시합니다. C 컴파일러에서 age 변수는 이 값을 저장하기 위해 3비트만 사용합니다. 3비트 이상을 사용하려고 하면 완료되지 않습니다. 다음 예를 살펴보겠습니다.

#include <stdio.h>#include <string.h>struct{  unsigned int age : 3;} Age;int main( ){   Age.age = 4;
   printf( "Sizeof( Age ) : %d\n", sizeof(Age) );
   printf( "Age.age : %d\n", Age.age );   Age.age = 7;
   printf( "Age.age : %d\n", Age.age );   Age.age = 8;
   printf( "Age.age : %d\n", Age.age );   return 0;}

위 코드를 컴파일하면 경고가 표시되고, 위 코드를 실행하면 다음과 같은 결과가 나타납니다.

Sizeof( Age ) : 4Age.age : 4Age.age : 7Age.age : 0