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에서 여러 데이터 유형이 있는 비트 필드
이제 구조에 두 개 이상의 데이터 유형이 있는 경우 비트 필드 저장 요구 사항을 논의할 적기입니다. 이 경우 필요한 최소 바이트는 구조에서 가장 큰 데이터 유형에 필요한 최대 공간입니다.
예를 들어 구조에 short
및 char
멤버가 있는 경우 가장 큰 유형은 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바이트가 필요합니다.
결론
프로그램에서 다중 비트 필드를 사용하면 공간을 절약할 수 있습니다. 선언 시 구조체 멤버 변수의 비트 수를 지정할 수 있습니다.
구조의 최소 크기는 구조에서 가장 큰 데이터 유형에 필요한 최대 바이트입니다.
단일 또는 다중 필드가 집합적으로 구조에서 가장 큰 유형의 크기보다 더 많은 비트를 소비하는 경우 소비되는 메모리는 최대 메모리 유형 크기의 배수가 됩니다.