C의 비트 필드

Abdul Mateen 2023년10월12일
  1. C의 비트 필드
  2. C의 비트 필드 저장
  3. C에서 짧은 데이터 유형이 있는 비트 필드
  4. C에서 여러 데이터 유형이 있는 비트 필드
  5. 결론
C의 비트 필드

이 튜토리얼에서는 C 언어의 비트 필드에 대해 알아봅니다.

비트 필드부터 논의를 시작하겠습니다. 다음으로 비트 필드 저장에 대해 설명하고 C 언어의 비트 필드 구문에 대해 설명합니다.

마지막으로 내부에 비트 필드가 있는 구조가 소비하는 최소 및 최대 공간을 이해하기 위해 다양한 데이터 유형의 비트 필드를 볼 것입니다.

C의 비트 필드

프로그래밍의 비트 필드는 프로그래머가 메모리를 절약하는 데 도움이 되는 고유한 데이터 구조입니다. 비트 필드를 사용하면 비트 단위의 구조에 메모리를 할당할 수 있습니다.

흑백 두 가지 색상만 있는 순수한 흑백 이미지를 생각해 봅시다. 0 또는 1의 두 값만 저장하면 됩니다.

각 차원에서 수천 개의 픽셀과 화면을 비교하는 작은 100x100 이미지를 고려하십시오. 이미지에는 10,000개의 픽셀이 있습니다.

표준 데이터 유형에는 1바이트만 사용하는 C 언어의 unsigned char 데이터 유형 옵션이 있습니다. 그러나 순수한 흑백 이미지를 저장하려면 10000바이트의 메모리가 필요합니다.

비트 필드를 사용하면 1바이트에 8픽셀(1바이트에 8비트)을 저장할 수 있습니다. 즉, 10000 대신 1250 바이트 정도가 필요합니다.

이것은 단지 예일 뿐입니다. 이것은 이미지의 경우에만 공간을 절약할 수 있다는 의미는 아닙니다. 수천 명의 응시자가 출제되는 일부 시험에서는 합격/불합격 정보를 저장하는 데 1비트만 필요합니다. 그렇지 않으면 옵션은 각 후보에 대해 1바이트를 사용하는 것입니다.

C의 비트 필드 저장

비트 필드 저장에 대한 논의를 시작하려면 다음 구조를 고려하십시오.

struct {
  unsigned char is_married;
  unsigned char is_graduated;
} status0;

이 구조에는 2바이트의 메모리 공간이 필요합니다. 그러나 두 필드 모두에 0 또는 1을 저장해야 합니다. 공간을 절약하는 더 나은 방법으로 이동합시다.

구문부터 코드까지 비트 필드를 자세히 살펴보겠습니다.

C 언어에는 각 변수에 필요한 비트 수를 알려주는 특정 구문이 있습니다.

struct {
  type[variable_name] : size;  // Size will be in bits
}

이 구문은 구조와 함께 사용할 수 있다는 점에 유의해야 합니다. 여기서 type은 int, char, short, unsigned char 등과 같은 모든 데이터 유형입니다.

당신은 이미 C 언어의 유효한 변수 이름을 잘 알고 있습니다. 콜론은 구문의 일부이며 변수 이름과 크기 사이에 필요하며 마지막으로 크기는 필요한 비트 수입니다.

당신을 놀라게 할 다음 것은 구조의 크기와 비트 크기입니다. 다음 코드를 참조하십시오.

#include <stdio.h>

struct {
  unsigned char is_married;
  unsigned char is_graduated;
} status0;

struct {
  unsigned char is_married : 1;
  unsigned char is_graduated : 1;
} status1;

int main() {
  printf("Memory size occupied by status1 : %ld bytes\n", sizeof(status0));
  printf("Memory size occupied by status1 : %ld  bytes\n", sizeof(status1));
  return 0;
}

출력은 다음과 같습니다.

Memory size occupied by status1 : 2 bytes
Memory size occupied by status1 : 1 bytes

출력에서 첫 번째 구조는 매우 논리적인 2바이트(즉, 각 필드에 대해 1바이트)를 사용합니다. 그러나 두 번째 출력은 1바이트를 사용합니다. 2바이트 또는 비트를 예상할 수 있습니다.

문제는 왜 1바이트인가 하는 것입니다. 논리는 데이터 유형이 C 언어의 루틴 정의당 1바이트를 소비한다는 것입니다.

그러나 크기를 비트로 지정하면 프로그래머가 각각 1비트인 필드를 7개 더 선언할 수 있습니다.

총 비트는 1바이트에 대해 8비트 이하로 유지되어야 합니다. 그렇지 않으면 2바이트의 저장 공간이 사용됩니다.

다음 코드를 참조하십시오.

#include <stdio.h>

struct {
  unsigned char a : 1;
  unsigned char b : 7;
} status0;

struct {
  unsigned char a : 1;
  unsigned char b : 1;
  unsigned char c : 1;
  unsigned char d : 1;
  unsigned char e : 1;
  unsigned char f : 1;
  unsigned char g : 1;
  unsigned char h : 1;
} status1;

int main() {
  printf("Memory size occupied by status1 : %ld\n", sizeof(status0));
  printf("Memory size occupied by status1 : %ld\n", sizeof(status1));
  return 0;
}

출력은 다음과 같습니다.

Memory size occupied by status1 : 1
Memory size occupied by status1 : 1

비트 수가 증가한 다음 예를 살펴보겠습니다.

#include <stdio.h>

struct {
  unsigned char a : 3;
  unsigned char b : 7;
  unsigned char c : 7;
} status0;

struct {
  unsigned char a : 1;
  unsigned char b : 1;
  unsigned char c : 1;
  unsigned char d : 1;
  unsigned char e : 1;
  unsigned char f : 1;
  unsigned char g : 1;
  unsigned char h : 1;
  unsigned char i : 1;
  unsigned char j : 1;
} status1;

int main() {
  printf("Memory size occupied by status1 : %ld\n", sizeof(status0));
  printf("Memory size occupied by status1 : %ld\n", sizeof(status1));
  return 0;
}

출력은 다음과 같습니다.

Memory size occupied by status1 : 3
Memory size occupied by status1 : 2

첫 번째 구조에서 전체 비트는 3+7+7=17이며 이는 16비트(2바이트)보다 큽니다. 따라서 3바이트가 소모됩니다.

출력의 첫 번째 줄에도 동일하게 표시됩니다.

두 번째 구조에는 각각 1비트의 10개 필드가 있으며 여기에는 10비트가 필요합니다. 따라서 2바이트를 사용합니다. 다시 출력의 두 번째 줄에서 개념을 확인합니다.

C에서 짧은 데이터 유형이 있는 비트 필드

비트 필드를 사용하려면 부호 없는 문자가 필요하다는 것을 알 수 있습니다. 다른 데이터 유형에도 비트 필드를 사용할 수 있습니다.

여기에서 우리는 비트 필드의 개념을 보여주고 이해하기 위해 짧은 데이터 유형을 고려하고 있습니다.

다음 코드를 고려하십시오.

#include <stdio.h>

struct {
  unsigned short a : 3;
} status0;

struct {
  unsigned short a : 3;
  unsigned short b : 9;
  unsigned short c : 4;
} status1;

int main() {
  printf("Memory size occupied by status1 : %ld\n", sizeof(status0));
  printf("Memory size occupied by status1 : %ld\n", sizeof(status1));
  return 0;
}

출력은 다음과 같습니다.

Memory size occupied by status1 : 2
Memory size occupied by status1 : 2

두 구조 모두 short가 2바이트를 차지하기 때문에 소비되는 메모리는 2바이트입니다. 따라서 필요한 최소 메모리는 2바이트입니다.

그러나 여러 필드는 총 16비트(두 번째 구조에 설명된 대로)를 사용할 수 있으며 크기는 2바이트로 유지됩니다.

비트 수가 16에서 증가하면 short 데이터 유형의 다음 2바이트가 자동으로 커버되므로 결과적으로 4개의 4가 소비됩니다.

다음 C 프로그램을 살펴보자.

#include <stdio.h>

struct {
  unsigned short a : 6;
  unsigned short b : 6;
  unsigned short c : 7;
} status1;

int main() {
  printf("Memory size occupied by status1 : %ld\n", sizeof(status1));
  return 0;
}

여기서 총 비트는 6+6+7=19이므로 출력은 다음과 같습니다.

Memory size occupied by status1 : 4

char에는 1바이트 저장 공간이 있으므로 메모리가 바이트 단위로 증가합니다. 반면 short의 경우 short는 정의에 따라 2바이트 저장 공간을 갖기 때문에 메모리가 2바이트씩 증가합니다.

C에서 여러 데이터 유형이 있는 비트 필드

이제 구조에 두 개 이상의 데이터 유형이 있는 경우 비트 필드 저장 요구 사항을 논의할 적기입니다. 이 경우 필요한 최소 바이트는 구조에서 가장 큰 데이터 유형에 필요한 최대 공간입니다.

예를 들어 구조에 shortchar 멤버가 있는 경우 가장 큰 유형은 short이며 2바이트가 필요합니다. 전체 구조에는 최소 2바이트가 필요합니다.

int & short의 경우 int가 가장 큰 유형입니다. 따라서 전체 구조에는 4바이트가 필요합니다. 다음 코드 예제를 통해 개념을 살펴보겠습니다.

#include <stdio.h>

struct {
  unsigned short a : 6;
  unsigned int b : 6;
} status1;

struct {
  unsigned long long a : 6;
  unsigned int b : 6;
  unsigned short c : 6;
} status2;

int main() {
  printf("Memory size occupied by status1 : %ld\n", sizeof(status1));
  printf("Memory size occupied by status1 : %ld\n", sizeof(status2));
  return 0;
}

출력은 다음과 같습니다.

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

첫 번째 구조에서 int는 가장 큰 데이터 유형입니다. 따라서 출력의 첫 번째 줄에는 4바이트 구조 크기가 표시됩니다.

두 번째 구조에서 long long은 지배적인 유형이므로 출력의 두 번째 줄에는 구조의 8바이트 크기가 표시됩니다.

마지막으로 여러 데이터 크기의 경우 증분은 간단합니다. 증분 단계는 크기가 가장 큰 구조 유형의 바이트 수와 같습니다.

이해를 돕기 위해 다음 코드를 살펴보겠습니다.

#include <stdio.h>

struct {
  unsigned short a : 6;
  unsigned int b : 30;
  unsigned long long c : 50;
} status1;

int main() {
  printf("Memory size occupied by status1 : %ld\n", sizeof(status1));
  return 0;
}

구조는 50+30+6=86비트를 갖는 반면 8바이트는 64비트를 갖습니다. 따라서 이 구조에는 아래 출력과 같이 이중 공간이 필요했습니다.

Memory size occupied by status1 : 16

8+8바이트인 16바이트가 필요합니다.

결론

프로그램에서 다중 비트 필드를 사용하면 공간을 절약할 수 있습니다. 선언 시 구조체 멤버 변수의 비트 수를 지정할 수 있습니다.

구조의 최소 크기는 구조에서 가장 큰 데이터 유형에 필요한 최대 바이트입니다.

단일 또는 다중 필드가 집합적으로 구조에서 가장 큰 유형의 크기보다 더 많은 비트를 소비하는 경우 소비되는 메모리는 최대 메모리 유형 크기의 배수가 됩니다.

관련 문장 - C Struct