Twitter und Facebook-Anbindung
X
Tweet Follow @twitterapi
!!! Anbindung an twitter und facebook öffnen !!!

Wenn Ihnen mein Online-Buch gefällt,
dann bedanken Sie sich doch mit einer kleinen Spende...

8.7 Bitfelder

8.7 Bitfelder

Bisher hatte ich immer verschwiegen, dass eine Variable nicht zwangsläufig so groß sein muss, wie vom System vorgegeben. Besser gesagt, sie ist intern meist trotzdem so groß, aber es ist möglich, nur einen Teil davon zu benutzen. Wenn man nach dem Variablennamen ein Doppelpunkt setzt, kann man anschließend angeben, wie viele Bits tatsächlich genutzt werden sollen.

Das Schema sieht so aus: <Datentyp> <VariablenName>:<Bitanzahl>;

Sie fragen sich jetzt bestimmt, wozu man das braucht? Nun, dafür möchte ich Ihnen einen zwar etwas komplizierten, aber richtig genialen Trick zeigen.

Normalerweise ist es ja so, dass jede Variable n Bytes benötigt. Eine boolesche Variable (also ein simples ja oder nein) benötigt so trotzdem 8 Bit, obwohl eins reichen würde. Gerade wenn man mehrere Flags benötigt, verbraucht man so viel Speicher. An dieser Stelle kommen Bitfelder ins Spiel, welche mit Unions effizienter werden. Ein Beispiel wäre hier verschiedene Rechte einer Datei. Sie kann z.B. schreibgeschützt und oder versteckt sein. Im folgenden Beispiel zeige ich, wie man diese Informationen alle in einer Variable bzw. in einem Byte speichern kann.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
					
union UFileStatus {
	// Anonyme Struktur
	struct {
		bool bHidden:1;
		bool bReadOnly:1;
		bool bEditable:1;
		bool bDeletable:1;
	}; unsigned char cFlags;
};

//...

UFileStatus	uStatus;
bool		bFlag;

printf("Size of UFileStatus %i\n", sizeof(UFileStatus));
printf("Size of bool        %i\n", sizeof(bool));

// Alle Flags deaktivieren
uStatus.cFlags		= 0;

// Zugriff auf einzelnes Flag
uStatus.bEditable	= true;
uStatus.bDeletable	= true;

printf("Wert von uStatus = %i\n", uStatus.cFlags);
					

Ausgabe:

Size of UFileStatus 1
Size of bool        1
Wert von uStatus = 12
		

Was ist jetzt hier passiert? Zunächst habe ich mir eine union gebaut, welche entweder eine Struktur bzw. ein vorzeichenloses Zeichen beinhaltet. Der Trick liegt hier in der anonymen Struktur. Sie ist so angelegt, dass sie nur vier Bit benötigt, wobei die erste Variable der Struktur das hinterste (also rechte) Bit ist. Das Zeichen wird in diesem Fall als eine Ganzzahl im Bereich von 0 bis 255 benutzt. In Zeile 16 beweise ich, dass die Variable tatsächlich nur ein Byte groß ist.

In Zeile 20 sehen Sie, wie man alle Flags zugleich auf "0" bzw. "false" setzen kann. In den Zeilen 23 bis 26 sehen Sie dann, wie man auf die einzelnen Bits zugreifen kann, ohne umständliche Bitoperationen ausführen zu müssen. Folgende Grafik soll noch einmal veranschaulichen, was im Speicher passiert.

Veranschaulichung eines Bitfeldes im Speicher

Die hinteren vier Bit werden also wie gewünscht benutzt. Die vorderen vier Bits sind nicht benutzt und deren Inhalt ist zufällig, wenn man sie nicht initialisiert.

Ich habe hier gezeigt, wie man also ein Byte bitweise ansteuern kann. Das Prinzip kann aber auch auf zwei oder mehr Byte angewendet werden. Dafür muss nur die Summe der benötigten Bits in der Struktur, zu einem Datentyp passen. Braucht man also in der Summe z.B. 24 Bit, also drei Byte, hätte "cFlags" mindestens ein Integer (32 Bit) sein müssen (es gibt standardmäßig keinen Datentyp, der drei Byte groß ist).

Natürlich ist es auch möglich, zwei oder mehr Bits pro Flag zu benutzen (beispielsweise wenn man nur Zahlen zwischen null und neun Speichern möchte, braucht man nur vier Bit), aber dies sollte mit Vorsicht genossen werden, da intern doch Bitoperationen durchgeführt werden müssen und jene sind wesentlich aufwendiger, wenn es sich um mehr als ein Bit handelt. Das hat zur Folge, dass das Programm geringfügig langsamer wird.

Zum Seitenanfang
Zum Inhaltsverzeichnis

© Copyright by Thomas Weiß, 2009 - 2012