구조 선언자는 구조체 또는 공용 구조체의 멤버에 대한 선언자일 뿐만 아니라 “비트 필드”라는 지정된 비트 수로 구성될 수도 있습니다. 해당 길이는 필드 이름에 대한 선언자에서 콜론으로 설정됩니다. 비트 필드는 정수 데이터 형식으로 해석됩니다.
구문
:
declarator
type-specifier
declarator
opt :
constant-expression
constant-expression
은 필드의 너비(비트)를 지정합니다. declarator
에 대한 type-specifier
는 unsigned int
, signed int
또는 int
여야 하고 constant-expression
은 음수가 아닌 정수 값이어야 합니다. 이 값이 0인 경우 선언에는 declarator
가 없습니다. 비트 필드의 배열, 비트 필드에 대한 포인터 및 비트 필드를 반환하는 함수는 허용되지 않습니다. 선택적 declarator
는 비트 필드 이름을 지정합니다. 비트 필드는 구조체의 일부로만 선언할 수 있습니다. address-of 연산자(&
)는 비트 필드 구성 요소에 적용할 수 없습니다.
명명되지 않은 비트 필드는 참조할 수 없으며 런타임에 해당 콘텐츠를 예측할 수 없습니다. 정렬 목적으로 "더미" 필드로 사용할 수 있습니다. 너비가 0으로 지정된 명명되지 않은 비트 필드의 경우 struct-declaration-list에서 해당 필드 다음에 나오는 멤버의 스토리지가 int
경계에서 시작됩니다.
비트 필드의 비트 수는 기본 형식의 크기보다 작거나 같아야 합니다. 예를 들어 다음 두 문은 올바르지 않습니다.
short a:17; /* Illegal! */
int long y:33; /* Illegal! */
이 예제에서는 screen
이라는 구조체의 2차원 배열을 정의합니다.
struct
{
unsigned short icon : 8;
unsigned short color : 4;
unsigned short underline : 1;
unsigned short blink : 1;
} screen[25][80];
이 배열에는 2,000개의 요소가 있습니다. 각 요소는 4개의 비트 필드 멤버, 즉 icon
, color
, underline
및 blink
를 포함하는 개별 구조체입니다. 각 구조체의 크기는 2바이트입니다.
비트 필드는 정수 형식과 의미 체계가 같습니다. 비트 필드는 동일한 기본 형식의 변수가 사용되는 것과 정확히 같은 방식으로 식에 사용됩니다. 비트 필드에 얼마나 많은 비트가 있는지는 중요하지 않습니다.
Microsoft 전용
int
로 정의된 비트 필드는 signed
로 처리됩니다. ANSI C 표준에 대한 Microsoft 확장은 비트 필드에 대해 char
및 long
형식( signed
및 unsigned
둘 다)을 허용합니다. 기본 형식 long
, short
또는 char
(signed
또는 unsigned
)을 갖는 명명되지 않은 비트 필드는 기본 형식에 맞게 강제로 경계에 맞춰 정렬됩니다.
비트 필드는 최하위 비트에서 최상위 비트까지 정수 내에 할당됩니다. 다음 코드에서
struct mybitfields
{
unsigned short a : 4;
unsigned short b : 5;
unsigned short c : 7;
} test;
int main( void )
{
test.a = 2;
test.b = 31;
test.c = 0;
return 0;
}
test
의 비트는 다음과 같이 정렬됩니다.
00000001 11110010
cccccccb bbbbaaaa
8086 프로세서 제품군은 높은 바이트 앞에 낮은 바이트의 정수 값을 저장하므로 정수 0x01F2
는 0x01
앞에 오는 0xF2
로 실제 메모리에 저장됩니다.
ISO C99 표준은 비트 필드가 두 스토리지 인스턴스를 포괄할 수 있는지를 선택할 수 있도록 합니다. 총 64비트인 비트 필드를 저장하는 이 구조체를 생각해 보겠습니다.
struct
{
unsigned int first : 9;
unsigned int second : 7;
unsigned int may_straddle : 30;
unsigned int last : 18;
} tricky_bits;
표준 C 구현은 이러한 비트 필드를 두 개의 32비트 정수로 압축할 수 있습니다. 32비트 정수 하나에 16비트로 tricky_bits.may_straddle
을 저장하고 다음 32비트 정수에 14비트로 저장할 수 있습니다. Windows ABI 규칙은 비트 필드를 단일 스토리지 정수로 압축하고, 스토리지 단위를 포괄하지 않습니다. Microsoft 컴파일러는 위의 예제에서 각 비트 필드를 저장하므로 단일 32비트 정수에 완전히 맞춰집니다. 이 경우 first
와 second
는 하나의 정수에 저장되고 may_straddle
은 두 번째 정수에 저장되고 last
는 세 번째 정수에 저장됩니다. sizeof
연산자는 tricky_bits
의 인스턴스에서 12
를 반환합니다. 자세한 내용은 구조체 멤버 패딩 및 맞춤을 참조하세요.
Microsoft 전용 종료