
Stell dir vor, du liest Code und siehst if (status == 2). Was bedeutet 2? Ein Fehler? Ein Zustand? Mit enum schreibst du stattdessen if (status == GELB) — sofort klar! Das ist der Kern von enum: lesbarer Code statt kryptischer Zahlen.
1. Was ist enum?
Ein enum (Enumeration = Aufzählung) ist ein Datentyp in C, der einer Menge von benannten ganzzahligen Konstanten Namen gibt. Das Ziel: "Magic Numbers" im Code zu ersetzen und den Code lesbarer zu machen.
❌ Ohne enum – Magic Numbers
Was bedeutet diese 2? Fehler? Status? Farbe?
if (ampel == 2) {
printf("Gruen!\n");
}
✅ Mit enum – sofort verständlich
GRUEN erklärt sich selbst!
if (ampel == GRUEN) {
printf("Gruen!\n");
}
Grundsyntax
/* Deklaration */ enum Farbe { ROT, GELB, GRUEN }; /* Standardwerte: ROT=0, GELB=1, GRUEN=2 */ int main() { enum Farbe ampel = ROT; /* ampel hat den Wert 0 */ printf("%d\n", ampel); /* gibt 0 aus */ return 0; }
Automatische Nummerierung
Der erste Eintrag bekommt standardmäßig den Wert 0, jeder weitere wird um 1 erhöht. enum { A, B, C } bedeutet: A=0, B=1, C=2.
2. typedef enum – kürzere Schreibweise
Mit enum Farbe muss man beim Variablentyp immer das Schlüsselwort enum davor schreiben. Mit typedef entfällt das:
/* Ohne typedef – umständlich */ enum Farbe { ROT, GELB, GRUEN }; enum Farbe ampel = ROT; /* "enum" muss immer dabei sein */ /* Mit typedef – viel kürzer */ typedef enum { ROT, GELB, GRUEN } Farbe; Farbe ampel = ROT; /* kein "enum" nötig! */
In der Praxis wird fast immer typedef enum verwendet, weil es den Code kürzer und lesbarer macht. Das ist der empfohlene Stil.
3. Praktisches Beispiel – Ampelsteuerung
Ein klassisches Anwendungsbeispiel: eine Ampel hat genau drei Zustände. Mit enum sind sie klar bennant und alle switch-Cases vollständig abgedeckt:
#include <stdio.h> typedef enum { ROT, GELB, GRUEN } Ampelfarbe; void zeige_ampel(Ampelfarbe farbe) { switch (farbe) { case ROT: printf("STOP – Rot!\n"); break; case GELB: printf("Achtung – Gelb!\n"); break; case GRUEN: printf("Fahrt frei – Gruen!\n"); break; } } int main() { Ampelfarbe a = GRUEN; zeige_ampel(a); /* Fahrt frei – Gruen! */ zeige_ampel(ROT); /* STOP – Rot! */ return 0; }
4. enum mit expliziten Werten
Man kann jedem enum-Eintrag einen eigenen Wert zuweisen. Nicht zugewiesene Einträge zählen ab dem letzten expliziten Wert weiter:
/* Explizite Werte – sinnvoll für Fehlercodes */ typedef enum { NIEDRIG = 1, MITTEL = 5, HOCH = 10 } Prioritaet; /* HTTP-Status-ähnliches Muster */ typedef enum { OK = 0, DATEI_FEHLER = 1, SPEICHER_FEHLER = 2, NETZ_FEHLER = 3 } Fehler; int main() { Fehler code = DATEI_FEHLER; printf("Fehlercode: %d\n", code); /* gibt 1 aus */ Prioritaet p = HOCH; printf("Prioritaet: %d\n", p); /* gibt 10 aus */ return 0; }
Wann explizite Werte sinnvoll sind
- Fehlercodes, die an externe Systeme übergeben werden
- Wenn die Zahlenwerte eine inhärente Bedeutung haben (HTTP-Codes: 200, 404, 500)
- Wenn Kompatibilität mit gespeicherten Werten (Datei/Datenbank) nötig ist
- Bei Prioritätssystemen mit Abständen (1, 5, 10 erlaubt späteres Einfügen)
5. enum in if-Bedingungen und Vergleichen
Da enum-Werte Ganzzahlen sind, funktionieren alle arithmetischen Vergleiche. Das macht enum ideal für Prioritätssysteme:
#include <stdio.h> typedef enum { NIEDRIG=1, MITTEL=5, HOCH=10 } Prioritaet; void pruefe_prio(Prioritaet p) { if (p >= HOCH) { printf("ALARM: Hohe Prioritaet!\n"); } else if (p >= MITTEL) { printf("Mittlere Prioritaet\n"); } else { printf("Niedrige Prioritaet\n"); } } int main() { pruefe_prio(HOCH); /* ALARM: Hohe Prioritaet! */ pruefe_prio(MITTEL); /* Mittlere Prioritaet */ pruefe_prio(NIEDRIG); /* Niedrige Prioritaet */ return 0; }
6. Wochentage-Beispiel (vollständig)
Ein vollständiges Beispiel: Wochentage als enum, beginnend bei 1 (Montag). Alle folgenden Werte werden automatisch weitergezählt — DI=2, MI=3 usw.
#include <stdio.h> /* MO=1, dann DI=2, MI=3, DO=4, FR=5, SA=6, SO=7 automatisch */ typedef enum { MO=1, DI, MI, DO, FR, SA, SO } Wochentag; int ist_wochenende(Wochentag t) { switch (t) { case SA: case SO: return 1; /* Wochenende */ default: return 0; /* Wochentag */ } } int main() { Wochentag tag; for (tag = MO; tag <= SO; tag++) { if (ist_wochenende(tag)) { printf("Tag %d: Wochenende!\n", tag); } else { printf("Tag %d: Arbeitstag\n", tag); } } return 0; }
7. Häufige Fehler
| Fehler | Problem | Lösung |
|---|---|---|
| enum == int direkt | Kompiliert, aber schlechter Stil und fehleranfällig | Enum-Namen verwenden, nicht Rohzahlen |
| Gleiche Namen in 2 enums | Namenskonflikt — Compiler-Fehler | Präfix benutzen: AMPEL_ROT, STATUS_ROT |
| Startet bei 0, nicht 1 | Off-by-One wenn als Array-Index verwendet | Erstes Element auf 1 setzen oder explizit mit =0 ankern |
| Strings in enum | Nicht möglich! enum { "ROT" } geht nicht | Lookup-Array: const char *namen[] = {"ROT","GELB","GRUEN"}; |
| Kein default in switch | Ungültige enum-Werte bleiben unbehandelt | Immer default: mit Fehlermeldung |
✅ Strings aus enum-Werten – Lookup-Array-Muster
Da enum keine Strings speichern kann, nutzt man ein paralleles Array:
const char *namen[] = { "Rot", "Gelb", "Gruen" };
printf("%s\n", namen[GELB]); /* gibt "Gelb" aus */
⚡ Code-Simulator
Schreibe C-Code links und führe ihn aus – der Simulator zeigt printf-Ausgaben sofort:

Ändere die enum-Werte oder füge einen neuen Zustand hinzu. Probiere auch printf("%d", GRUEN) aus — du siehst, dass GRUEN intern die Zahl 2 ist!
🎯 Wissens-Quiz
enum { X=5, Y, Z }; — welchen Wert hat Y?#define-Konstanten?enum { A, B, C }; printf("%d", C);📋 Spickzettel
✅ Checkliste Unit 31
- Ich verstehe den Unterschied zwischen enum und Magic Numbers
- Ich kann typedef enum korrekt deklarieren und verwenden
- Ich weiß, wie die automatische Nummerierung funktioniert
- Ich kann explizite Werte in einem enum vergeben
- Ich kann enum mit switch-case und if-Bedingungen einsetzen
- Ich kenne das Lookup-Array-Muster für Strings aus enum-Werten