Pola bitowe języka C
Oprócz deklaratorów dla elementów członkowskich struktury lub unii deklarator struktury może być również określoną liczbą bitów, nazywanych "polem bitowym". Jego długość jest ustawiana od deklaratora dla nazwy pola dwukropkiem. Pole bitowe jest interpretowane jako typ całkowity.
Składnia
struct-declarator
:
declarator
type-specifier
declarator
Zdecydować :
constant-expression
Parametr constant-expression
określa szerokość pola w bitach. Wartość type-specifier
dla declarator
elementu musi mieć unsigned int
wartość , signed int
lub int
, a constant-expression
wartość musi być wartością nienależącą do liczby całkowitej. Jeśli wartość ma wartość zero, deklaracja nie declarator
ma wartości . Tablice pól bitowych, wskaźniki do pól bitowych i funkcje zwracające pola bitowe nie są dozwolone. Opcjonalne declarator
nazwy pola bitowego. Pola bitowe można zadeklarować tylko jako część struktury. Nie można zastosować operatora adresu (&
) do składników pól bitowych.
Nie można odwoływać się do nienazwanych pól bitowych, a ich zawartość w czasie wykonywania jest nieprzewidywalna. Można ich używać jako "fikcyjnych" pól do celów wyrównania. Nienazwane pole bitowe, którego szerokość jest określona jako 0, gwarantuje, że magazyn dla elementu członkowskiego po nim na liście deklaracji struktury rozpoczyna się na int
granicy.
Liczba bitów w polu bitowym musi być mniejsza lub równa rozmiarowi typu bazowego. Na przykład te dwie instrukcje nie są legalne:
short a:17; /* Illegal! */
int long y:33; /* Illegal! */
W tym przykładzie zdefiniowano dwuwymiarową tablicę struktur o nazwie screen
.
struct
{
unsigned short icon : 8;
unsigned short color : 4;
unsigned short underline : 1;
unsigned short blink : 1;
} screen[25][80];
Tablica zawiera 2000 elementów. Każdy element jest pojedynczą strukturą zawierającą cztery elementy członkowskie pól bitowych: icon
, , color
underline
i blink
. Rozmiar każdej struktury wynosi 2 bajty.
Pola bitowe mają te same semantyki co typ liczby całkowitej. Pole bitowe jest używane w wyrażeniach w taki sam sposób, jak zmienna tego samego typu podstawowego. Nie ma znaczenia, ile bitów znajduje się w polu bitowym.
Specyficzne dla firmy Microsoft
Pola bitowe zdefiniowane jako int
są traktowane jako signed
. Rozszerzenie firmy Microsoft do standardu ANSI C zezwala i char
long
typy (zarówno signed
i unsigned
) dla pól bitowych. Pola bitowe bez nazw z typem long
podstawowym , short
lub (signed
lub unsigned
char
) wymuszają wyrównanie do granicy odpowiedniej dla typu podstawowego.
Pola bitowe są przydzielane w obrębie liczby całkowitej z najmniej znaczącego do najbardziej znaczącego bitu. W poniższym kodzie
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;
}
bity elementu test
zostaną ułożone w następujący sposób:
00000001 11110010
cccccccb bbbbaaaa
Ponieważ rodzina procesorów 8086 przechowuje niski bajt wartości całkowitych przed wysokim bajtem, liczba całkowita 0x01F2
będzie przechowywana w pamięci fizycznej, a 0xF2
następnie 0x01
.
Standard ISO C99 umożliwia implementacji wybranie, czy pole bitowe może straddle dwóch wystąpień magazynu. Rozważmy tę strukturę, która przechowuje pola bitowe o łącznej wartości 64 bitów:
struct
{
unsigned int first : 9;
unsigned int second : 7;
unsigned int may_straddle : 30;
unsigned int last : 18;
} tricky_bits;
Standardowa implementacja języka C może spakować te pola bitowe na dwie 32-bitowe liczby całkowite. Może ona przechowywać tricky_bits.may_straddle
jako 16 bitów w jednej 32-bitowej liczbą całkowitą i 14 bitami w następnej 32-bitowej liczbą całkowitą. Konwencje ABI systemu Windows pakują pola bitowe do pojedynczych liczb całkowitych magazynu i nie oddziela jednostek magazynu. Kompilator firmy Microsoft przechowuje każde pole bitowe w powyższym przykładzie, dzięki czemu pasuje całkowicie do jednej 32-bitowej liczby całkowitej. W tym przypadku first
i second
są przechowywane w jednej liczbą całkowitą, may_straddle
są przechowywane w drugiej liczbą całkowitą i last
są przechowywane w trzeciej liczbą całkowitą. Operator sizeof
zwraca 12
wystąpienie tricky_bits
klasy . Aby uzyskać więcej informacji, zobacz Dopełnianie i wyrównanie składowych struktury.
END Microsoft Specific