Die Sprache C ist winzig - Typen, Operatoren, Kontrollfluss, Funktionen, Zeiger. Sie kann nichts ausgeben, keine Datei lesen, keine Zeichenkette vergleichen und keinen Speicher belegen. All das ist die Standardbibliothek: ein Satz Header, den jede standardkonforme Implementierung ausliefert.
Diese Seite ist eine Karte. Jeder Abschnitt sagt, wofür ein Header da ist, zeigt ein kurzes lauffähiges Beispiel und verweist auf die ausführlichere Seite, wo es eine gibt.
stdio.h - Ein- und Ausgabe
Der Header, den du in fast jedem Programm zuerst einbindest. Er hält printf und scanf, den Typ FILE und die Dateifunktionen sowie die sichereren zeilenorientierten Eingabefunktionen.
Das Wesentliche: printf, fprintf, sprintf, snprintf für die Ausgabe; scanf, fscanf, sscanf, fgets, getchar für die Eingabe; fopen, fclose, fread, fwrite, fseek für Dateien. Tiefere Behandlung steht unter printf, scanf und Dateiverarbeitung.
Eine Regel, die man mitnehmen sollte: Benutze nie gets(). Es hat keine Möglichkeit, die Größe deines Puffers zu kennen, und wurde in C11 aus dem Standard entfernt. fgets(buf, sizeof buf, stdin) ist der Ersatz.
stdlib.h - allgemeine Werkzeuge
Das Sammelbecken: Speicher, Umwandlungen, Zufall, Prozesssteuerung, Sortieren.
Höhepunkte: malloc, calloc, realloc, free (siehe dynamischer Speicher); atoi, atof, strtol, strtod für Umwandlungen - bevorzuge die strto*-Familie, die einen Fehlschlag melden kann, wo atoi still 0 liefert; rand und srand (siehe Zufallszahlen); exit, abort, getenv, system; sowie qsort/bsearch.
string.h - Zeichenketten und Speicherblöcke
C-Zeichenketten sind char-Arrays, die mit '\0' enden, und jede Operation auf ihnen ist ein Funktionsaufruf.
Zwei Gewohnheiten bewahren diesen Header davor, eine Quelle von Pufferüberläufen zu werden: Kenne immer die Größe des Ziels, und denk daran, dass strcmp bei Gleichheit 0 liefert - if (strcmp(a, b)) ist wahr, wenn die Zeichenketten sich unterscheiden. Zeichenkettenfunktionen behandelt die sichereren strncpy/snprintf-Muster ausführlich.
math.h - Mathematik
sqrt, pow, fabs, floor, ceil, round, fmod, die Trigonometrie- und Logarithmusfamilien, INFINITY und NAN.
Das ist der eine Header, der ein Linker-Flag brauchen kann: Füge unter Linux -lm ans Ende des Übersetzungsbefehls, sonst meldet der Linker „undefined reference to sqrt". Die volle Tour steht unter Mathematikfunktionen.
time.h - Uhren und Daten
Die zwei Verschiebungen in struct tm erwischen jeden: tm_year zählt ab 1900, und tm_mon ist nullbasiert. time(NULL) ist auch der übliche Startwert für srand.
ctype.h - Zeichenklassifizierung
Klein und nützlicher, als es aussieht. Jede Funktion nimmt ein Zeichen entgegen und beantwortet eine Ja/Nein-Frage oder wandelt die Groß-/Kleinschreibung um.
Der vollständige Satz: isalpha, isdigit, isalnum, isspace, isupper, islower, ispunct, isxdigit, isprint, dazu toupper und tolower.
Beachte den Cast (unsigned char). Diese Funktionen sind für Werte definiert, die als unsigned char darstellbar sind, plus EOF; ein schlichtes char ist auf den meisten Systemen vorzeichenbehaftet, ein Byte über 127 kommt also als negative Zahl an und der Aufruf wird zu undefiniertem Verhalten. Der Cast kostet nichts und beseitigt die ganze Problemklasse.
Und bevorzuge sie gegenüber selbstgebauten Tests. c >= '0' && c <= '9' funktioniert zufällig, aber isdigit(c) sagt, was du meinst, und bleibt überall korrekt.
limits.h und float.h - die Ränder der Typen
Wie groß kann ein int auf dieser Maschine werden? Diese Header beantworten das, und die Antworten sind der Grund, warum portabler Code fragt statt anzunehmen.
INT_MAX ist die Art, auf einen Überlauf zu prüfen, bevor er passiert, und das zählt, weil ein vorzeichenbehafteter Überlauf undefiniertes Verhalten ist und kein Umschlagen, das du hinterher testen könntest.
stdbool.h und stdint.h - bessere Typen
C hatte bis C99 keinen Wahrheitstyp. <stdbool.h> liefert einen:
bool, true und false sind Makros für _Bool, 1 und 0, aber sie machen die Absicht offensichtlich. (In C23 wurden sie Schlüsselwörter und der Header ist nicht mehr nötig.)
<stdint.h> gibt dir Typen mit garantierten Breiten - unverzichtbar für Dateiformate, Netzprotokolle und alles Eingebettete, wo „ein int hat wahrscheinlich 32 Bit" nicht gut genug ist:
Die Makros im Stil PRId32 aus <inttypes.h> expandieren zur korrekten printf-Angabe für jeden Typ fester Breite auf der aktuellen Plattform - und das ist die portable Art, sie auszugeben, denn %d ist auf manchen Systemen für int32_t richtig und auf anderen falsch.
assert.h - deine Annahmen prüfen
assert(ausdruck) tut nichts, wenn der Ausdruck wahr ist, und bricht das Programm mit einer Meldung ab, wenn er falsch ist.
Mit -DNDEBUG zu kompilieren entfernt jede Zusicherung, sie kosten in einem Release-Build also nichts. Das ist zugleich die Warnung: Setze nie eine Nebenwirkung in ein assert. assert(read_next() > 0) hört im Release-Build ganz auf zu lesen, und der entstehende Bug taucht nur in der Produktion auf.
Zusicherungen sind für deine Fehler gedacht - Bedingungen, die unmöglich sein sollten, wenn der Code korrekt ist. Eine schlechte Benutzereingabe ist keine Zusicherung; sie ist ein if und eine Fehlermeldung.
Der Rest, kurz gefasst
<stddef.h>-size_t,ptrdiff_t,NULL,offsetof<stdarg.h>- Funktionen mit variabler Argumentzahl, die Maschinerie hinterprintf<errno.h>-errnoplusperrorundstrerror, um zu melden, warum ein Aufruf scheiterte<signal.h>- Signale behandeln, etwa Strg-C<setjmp.h>- nichtlokale Sprünge; selten die richtige Antwort<locale.h>,<wchar.h>,<wctype.h>- Locales und breite Zeichen<stdnoreturn.h>,<stdalign.h>,<threads.h>,<stdatomic.h>- Ergänzungen aus C11
Zwei Gewohnheiten machen die Bibliothek angenehm zu benutzen. Lies die Handbuchseite, statt eine Signatur zu erraten - man 3 strtol unter macOS und Linux ist maßgeblich und schnell. Und prüfe Rückgabewerte: malloc, fopen und strtol melden alle einen Fehlschlag, und ein Programm, das sie ignoriert, scheitert viel später und viel unklarer.
Häufig gestellte Fragen
Was ist die C-Standardbibliothek?
Die Menge an Funktionen, Typen und Makros, die jede standardkonforme C-Implementierung bereitstellt, gruppiert in etwa 30 Header. Sie deckt Ein- und Ausgabe (<stdio.h>), Speicher und Umwandlungen (<stdlib.h>), Zeichenketten (<string.h>), Mathematik (<math.h>), Zeit, Zeichenklassifizierung und die Grenzen der numerischen Typen ab. C hat keine eingebaute Ein-/Ausgabe und keine Zeichenkettenverarbeitung - alles davon kommt von hier.
Was ist der Unterschied zwischen stdio.h und stdlib.h?
<stdio.h> ist Ein- und Ausgabe: printf, scanf, fopen, fgets, FILE. <stdlib.h> sind allgemeine Werkzeuge: malloc und free, atoi und strtol, rand und srand, exit, qsort, bsearch. Ein typisches Programm bindet beide ein.
Was macht ctype.h?
Es klassifiziert und wandelt einzelne Zeichen um: isdigit, isalpha, isalnum, isspace, isupper, islower, ispunct, dazu toupper und tolower. Sie statt handgeschriebener Vergleiche wie c >= '0' && c <= '9' zu benutzen ist klarer und für jede Locale und jeden Zeichensatz korrekt.
Muss ich etwas linken, um die C-Standardbibliothek zu benutzen?
Nein, mit einer Ausnahme: den Mathematikfunktionen. Die Standard-C-Bibliothek wird automatisch gelinkt, aber unter Linux liegen die Implementierungen von <math.h> in einer eigenen Bibliothek, sqrt und Verwandte brauchen also -lm am Ende des Übersetzungsbefehls. Alles andere braucht nur das richtige #include.