📚 Kapitel 7 · Unit 35 von 36

Bitoperatoren
Bit-Manipulation in C

AND / OR / XOR / NOT · Shift-Operatoren · Bit-Masken · Flags · Embedded-Praxis

35 / 36 Units
Ömer
Kapitel 7: Fortgeschrittene Konzepte ~100 Min. Theorie + Simulator + Quiz + Spickzettel
Ömer
Ömer sagt:

Bitoperatoren sind das Handwerkszeug der Embedded-Programmierer! Hardware-Register, Berechtigungsflags, RGB-Farben – alles läuft auf Bit-Ebene. Das ist eines der coolsten Themen in C!

Binäre Darstellung

Jede Ganzzahl wird im Computer als Folge von Bits (0 oder 1) gespeichert. Ein int hat 32 Bits:

42
0
0
0
0
0
0
0
0
...
0
0
1
0
1
0
1
0
= 32+8+2 = 42
DezimalBinär (4 Bit)DezimalBinär (4 Bit)
0000081000
1000191001
20010101010
30011121100
40100141110
70111151111

Schlüsselwerte: Potenzen von 2

1=0001, 2=0010, 4=0100, 8=1000, 16=0001 0000 … Diese Werte haben genau ein Bit gesetzt – perfekt als Bit-Masken!

Die 6 Bitoperatoren

OperatorNameBeispiel (4 Bit)Ergebnis
&UND (AND)1010 & 11001000 = 8
|ODER (OR)1010 | 11001110 = 14
^XOR (exklusiv-ODER)1010 ^ 11000110 = 6
~NOT (Komplement)~0000 10101111 0101
<<Links-Shift0001 << 20100 = 4
>>Rechts-Shift1000 >> 20010 = 2

So funktioniert AND, OR und XOR Bit für Bit:

10 (A)
1
0
1
0
12 (B)
1
1
0
0
A & B
1
0
0
0
= 8
A | B
1
1
1
0
= 14
A ^ B
0
1
1
0
= 6

Bit setzen, löschen, prüfen (Bit-Masken)

Das sind die vier grundlegenden Bit-Operationen die du auswendig kennen solltest:

bit_masken.cC
unsigned int x = 0;

/* Bit n SETZEN  (auf 1) */
x |=  (1 << n);

/* Bit n LÖSCHEN (auf 0) */
x &= ~(1 << n);

/* Bit n UMSCHALTEN (toggle) */
x ^=  (1 << n);

/* Bit n PRÜFEN */
if (x & (1 << n)) {
    printf("Bit %d ist gesetzt!\n", n);
}

Praxisbeispiel mit Unix-ähnlichen Berechtigungs-Flags:

flags.cC
#include <stdio.h>

#define FLAG_READ    1   // 001
#define FLAG_WRITE   2   // 010
#define FLAG_EXEC    4   // 100

int main() {
    unsigned int rechte = 0;

    rechte |= FLAG_READ;     // Lesen erlauben
    rechte |= FLAG_WRITE;    // Schreiben erlauben
    // rechte = 011 = 3

    if (rechte & FLAG_EXEC)
        printf("Ausführen: JA\n");
    else
        printf("Ausführen: NEIN\n");

    rechte &= ~FLAG_WRITE;    // Schreiben entziehen
    printf("Rechte-Wert: %u\n", rechte);
    return 0;
}
Ausgabe
Ausführen: NEIN Rechte-Wert: 1

Shift = Multiplizieren / Dividieren mit 2

Links-Shift << entspricht einer Multiplikation mit einer 2er-Potenz – und das ist extrem schnell, weil keine Division nötig ist:

AusdruckDezimalEntspricht
1 << 011 × 1
1 << 121 × 2
1 << 241 × 4
1 << 381 × 8
1 << 4161 × 16
16 >> 2416 ÷ 4

Praxisbeispiel: Gerade/Ungerade mit &

Das letzte Bit einer Zahl verrät ob sie gerade oder ungerade ist. Das ist schneller als % 2!

gerade.cC
#include <stdio.h>

int main() {
    for (int i = 1; i <= 8; i++) {
        if (i & 1)
            printf("%d ist ungerade\n", i);
        else
            printf("%d ist gerade\n", i);
    }
    return 0;
}

Anwendungen in der Praxis (HTL-relevant)

Embedded: Hardware-Register

Microcontroller haben Register deren einzelne Bits bestimmte Hardware-Funktionen steuern. Bit setzen/löschen ist die Grundoperation in Embedded-C.

PORTA |= (1 << 3); // Pin 3 high

Flags in einer Zahl

Viele Bits in einer Zahl speichern – spart Speicher und ist schnell. Wie Unix rwx-Berechtigungen: r=4, w=2, x=1.

755 = 111 101 101 (binär)

Netzwerk: IP & Subnetz

IP-Adressen und Subnetz-Masken werden mit AND verknüpft um den Netzwerkteil zu ermitteln.

ip & maske = netzwerk

Grafik: RGB in 32-bit int

Eine Farbe besteht aus R, G, B (je 8 Bit). Alle drei lassen sich in einem einzigen int speichern:

rgb = (r<<16) | (g<<8) | b
rgb.cC
unsigned int r = 255, g = 128, b = 0;

/* Farbe packen */
unsigned int rgb = (r << 16) | (g << 8) | b;

/* Farbe entpacken */
unsigned int rot   = (rgb >> 16) & 0xFF;
unsigned int gruen = (rgb >>  8) & 0xFF;
unsigned int blau  =  rgb         & 0xFF;

printf("RGB: #%06X\n", rgb);
printf("R=%u G=%u B=%u\n", rot, gruen, blau);
Ausgabe
RGB: #FF8000 R=255 G=128 B=0

Häufige Fehler

Fehler 1: & vs &&

& ist bitweises AND. && ist logisches AND. Komplett unterschiedliche Semantik! if (a & b) ist nicht dasselbe wie if (a && b).

Fehler 2: | vs ||

Genauso: | ist bitweises OR, || ist logisches OR. Nie verwechseln!

Fehler 3: Shift negativer Zahlen

Shift von negativen Zahlen ist undefiniertes Verhalten in C. Immer unsigned für Bit-Manipulation verwenden!

Fehler 4: Shift ≥ Bit-Breite

1 << 32 bei einem 32-bit int ist undefiniert. Shift-Betrag muss kleiner als die Bit-Breite des Typs sein.

Bitoperatoren-Simulator

Gib zwei Zahlen ein und wähle einen Operator. Der Simulator zeigt das Ergebnis und die binäre Darstellung:

Bitweise Operationen – Unit 35
Zahl A: Zahl B:
– Klicke auf BERECHNEN –
Ömer
Ömer sagt:

Probiere verschiedene Kombinationen! XOR mit sich selbst ergibt immer 0. Shift links verdoppelt. Und NOT kehrt alle Bits um – das ist das bitweise Komplement.

Quiz – Bitoperatoren

Frage 1
Was ergibt 5 & 3? (101 & 011)
A1
B7
C6
D15
Frage 2
Was ergibt 5 | 3? (101 | 011)
A1
B7
C5
D3
Frage 3
Was bedeutet x |= (1 << 2)?
ABit 2 auf 0 setzen
BBit 2 auf 1 setzen
Cx mit 2 multiplizieren
Dx um 2 Bits links verschieben
Frage 4
Was ergibt 4 >> 1?
A8
B2
C1
D16
Frage 5
Was ist x & 1 wenn x ungerade ist?
A0
B1
Cx selbst
D-1
Frage 6
Was ist der Unterschied zwischen & und &&?
AKein Unterschied, beide sind logisches AND
B& ist bitweise AND, && ist logisches AND
C&& ist schneller als &
D& funktioniert nur mit unsigned
Frage 7
Was ergibt 6 ^ 6?
A0 (XOR mit sich selbst ergibt immer 0)
B6
C12
D1
Frage 8
Welcher Ausdruck löscht Bit 3 in Variable x?
Ax |= (1 << 3)
Bx ^= (1 << 3)
Cx &= ~(1 << 3)
Dx >>= 3

Spickzettel – Bitoperatoren

Die 6 Operatoren
a & bUND: beide Bits 1
a | bODER: mind. 1 Bit
a ^ bXOR: genau 1 Bit
~aNOT: alle Bits kippen
a << nLinks-Shift × 2^n
a >> nRechts-Shift ÷ 2^n
Bit set/clear/toggle/check
x |= (1<<n)Bit n setzen
x &= ~(1<<n)Bit n löschen
x ^= (1<<n)Bit n umschalten
x & (1<<n)Bit n prüfen
Shift = × / ÷ 2
x << 1x × 2
x << 3x × 8
x >> 1x ÷ 2
x & 1ungerade Test
Unix-Flags (rwx)
#define READ 1001
#define WRITE 2010
#define EXEC 4100
READ|WRITE= 3 = 011

Checkliste Unit 35

  • Ich kenne alle 6 Bitoperatoren und ihre Bedeutung
  • Ich kann Bits setzen, löschen, umschalten und prüfen
  • Ich verstehe Shift als schnelle Multiplikation/Division
  • Ich kenne den Unterschied zwischen & und &&
  • Ich kann Bit-Masken für Flags und RGB einsetzen