C-Bitfelder
Zusätzlich zu Deklaratoren für Member einer Struktur oder Union kann ein Strukturdeklarator auch eine festgelegte Anzahl von Bits sein, die als „Bitfeld“ bezeichnet wird. Die Länge des Bitfelds wird durch einen Doppelpunkt vom Deklarator des Namens getrennt. Ein Bitfeld wird als Ganzzahltyp interpretiert.
Syntax
struct-declarator
:
declarator
type-specifier
declarator
opt:
constant-expression
constant-expression
gibt die Breite des Felds in Bits an. Der type-specifier
für den declarator
muss unsigned int
, signed int
oder int
sein, und constant-expression
muss ein nicht negativer Ganzzahlwert sein. Falls der Wert 0 (null) ist, weist die Deklaration keinen declarator
auf. Arrays aus Bitfeldern, Zeiger auf Bitfelder und Funktionen, die Bitfelder zurückgeben, sind nicht zulässig. Der optionale declarator
benennt das Bitfeld. Bitfelder können nur als Teil einer Struktur deklariert werden. Der address-of-Operator (&
) kann nicht auf Bitfeldkomponenten angewendet werden.
Auf unbenannte Bitfelder kann nicht verwiesen werden, und deren Inhalt zur Laufzeit ist unvorhersehbar. Sie können als "Dummy"-Felder zu Ausrichtungszwecken verwendet werden. Ein unbenanntes Bitfeld, dessen Breite auf 0 festgelegt ist, garantiert, dass der Speicher für das in struct-declaration-list nachfolgende Element an einer int
-Grenze beginnt.
Die Anzahl der Bits in einem Bitfeld muss kleiner oder gleich der Größe des zugrunde liegenden Typs sein. Beispielsweise sind die folgenden beiden Anweisungen nicht zulässig:
short a:17; /* Illegal! */
int long y:33; /* Illegal! */
In diesem Beispiel wird ein zweidimensionales Array von Strukturen mit dem Namen screen
definiert.
struct
{
unsigned short icon : 8;
unsigned short color : 4;
unsigned short underline : 1;
unsigned short blink : 1;
} screen[25][80];
Das Array enthält 2.000 Elemente. Jedes Element ist eine einzelne Struktur, die vier Bitfeldmember enthält: icon
, color
, underline
und blink
. Die Größe der einzelnen Strukturen beträgt zwei Bytes.
Bitfelder weisen die gleiche Semantik wie der Ganzzahltyp auf. Ein Bitfeld in Ausdrücken wird auf genau die gleiche Weise verwendet wie eine Variable des gleichen Basistyps. Dies gilt unabhängig davon, wie viele Bits das Bitfeld aufweist.
Microsoft-spezifisch
Bitfelder, die als int
definiert sind, werden als signed
behandelt. Eine Microsoft-Erweiterung für den ANSI C-Standard erlaubt die Typen char
und long
(sowohl signed
als auch unsigned
) für Bitfelder. Unbenannte Bitfelder mit dem Basistyp long
, short
oder char
(signed
oder unsigned
) erzwingen eine Ausrichtung an einer für den Basistyp geeigneten Grenze.
Bitfelder werden innerhalb einer Ganzzahl vom niedrigstwertigen hin zum höchstwertigen Bit angeordnet. Im folgenden Code etwa
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;
}
wären die Bits von test
folgendermaßen angeordnet:
00000001 11110010
cccccccb bbbbaaaa
Da die Familie der 8086-Prozessoren das niederwertige Byte ganzzahliger Werte vor dem höherwertigen Byte speichert, würde die Ganzzahl 0x01F2
im physischen Speicher als 0xF2
gefolgt von 0x01
gespeichert werden.
Mit dem ISO C99-Standard kann eine Implementierung auswählen, ob ein Bitfeld auf zwei Speicherinstanzen aufgeteilt werden darf. Sehen Sie sich diese Struktur an, in der Bitfelder mit einer Gesamtanzahl von 64 Bits gespeichert werden:
struct
{
unsigned int first : 9;
unsigned int second : 7;
unsigned int may_straddle : 30;
unsigned int last : 18;
} tricky_bits;
Eine C-Standardimplementierung könnte diese Bitfelder in zwei 32-Bit-Integern speichern. Sie könnte tricky_bits.may_straddle
als 16 Bits in einem 32-Bit-Integer und als 14 Bits im nächsten 32-Bit-Integer speichern. Die Windows ABI-Konvention speichert Bitfelder in einzelnen Speicherintegern und teilt Speichereinheiten nicht auf. Der Microsoft-Compiler speichert jedes Bitfeld im obigen Beispiel so, dass es vollständig in einen 32-Bit-Integer passt. In diesem Fall werden first
und second
in einem Integer, may_straddle
in einem zweiten Integer und last
in einem dritten Integer gespeichert. Der Operator sizeof
gibt 12
für eine Instanz von tricky_bits
zurück. Weitere Informationen finden Sie unter Abstand und Ausrichtung von Strukturmembern.
Ende Microsoft-spezifisch
Siehe auch
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für