Kapitel 12 Präprozessor-Direktiven
In diesem Kapitel erfahren Sie einiges zum Präprozessor. Der Präprozessor ist ein Teil des Compilers, der noch vor der Übersetzung einige Änderungen am Quelltext vornimmt.
Wenn in der Sprache C ein Programm übersetzt (kompiliert und gelinkt) werden soll, dann wird, bevor der Compiler den Quelltext verarbeitet, von einem besonderen Teil des Compilers, dem Präprozessor, ein zusätzlicher Übersetzungslauf durchgeführt. Präprozessor-Direktiven beginnen immer mit dem Zeichen # am Anfang der Zeile. Außerdem darf pro Zeile nur eine Direktive eingesetzt werden. Folgendes ist also nicht erlaubt:
#include <stdio.h> #include <stdlib.h>
Kommentare hingegen dürfen sehr wohl hinter einer Direktive stehen.
#include <stdio.h> /* Headerdatei für Standardfunktionen */
Die folgenden Arbeiten fallen für den Präprozessor neben der Quelltextersetzung ebenfalls an:
|
String-Literale werden zusammengefasst (konkateniert). |
|
Zeilenumbrüche mit einem Backslash am Anfang werden entfernt. |
|
Kommentare werden entfernt und durch Leerzeichen ersetzt. |
|
Whitespace-Zeichen zwischen Tokens werden gelöscht. |
Des Weiteren gibt es Aufgaben für den Präprozessor, die vom Programmierer gesteuert werden können:
|
Header- und Quelldateien in den Quelltext kopieren (#include) |
|
Symbolische Konstanten einbinden (#define) |
|
Bedingte Kompilierung (#ifdef, #elseif, ...) |
Auf die Präprozessor-Direktiven, die Sie als Programmierer selbst steuern können, soll auf den folgenden Seiten eingegangen werden.
12.1 Einkopieren von Dateien mittels #include
 
Die Direktive #include kopiert andere, benannte (Include-) Dateien in das Programm ein. Meistens handelt es sich dabei um Headerdateien mit der Extension *.h oder *.hpp. Hier die Syntax der Präprozessor-Direktive include:
#include <header >
#include "header"
Der Präprozessor entfernt die include-Zeile und ersetzt diese durch den Quelltext der include-Datei. Der Compiler erhält anschließend einen modifizierten Text zur Übersetzung.
Natürlich können Sie damit eigene Headerdateien schreiben und diese einkopieren lassen. Sie haben beispielsweise eine Headerdatei geschrieben und diese im Verzeichnis /HOME/MYOWNHEADERS unter dem Namen meinheader.h gespeichert. Dann müssen Sie diese Headerdatei am Anfang des Quelltextes mit
#include "/home/myownheaders/meinheader.h"
einkopieren. Dabei muss dasjenige Verzeichnis angegeben werden, in dem die Headerdatei gespeichert wurde. Steht die Headerdatei hingegen zwischen eckigen Klammern (wie dies bei Standardbibliotheken meistens der Fall ist), also:
#include <datei.h>
so wird die Headerdatei datei.h im implementierungsdefinierten Pfad gesucht. Dieser Pfad befindet sich in dem Pfad, in dem sich die Headerdateien Ihres Compilers befinden.
Steht die Headerdatei zwischen zwei Hochkommata, also:
#include "datei.h"
so wird diese im aktuellen Arbeitsverzeichnis oder in dem Verzeichnis gesucht, das mit dem Compiler-Aufruf -I angegeben wurde – vorausgesetzt, Sie übersetzen das Programm in der Kommandozeile. Sollte diese Suche erfolglos sein, so wird in denselben Pfaden gesucht als wäre #include <datei.h> angegeben.
Hier die einzelnen Schritte, durch die aus dem Quellcode eine ausführbare Datei wird (von oben nach unten):
 Hier klicken, um das Bild zu Vergrößern
Abbildung 12.1
Von der Quelldatei zur ausführbaren Datei
Dazu eine Übersicht zu den Standard-Headerdateien, die von ANSI C vorgeschrieben sind:
Tabelle 12.1
Übersicht zu den Standard-Headerdateien (C89)
| Headerdatei
|
Bedeutung
|
| assert.h
|
Fehlersuche und Debugging
|
| ctype.h
|
Zeichentest und Konvertierung
|
| errno.h
|
Fehlercodes
|
| float.h
|
Limits/Eigenschaften für Gleitpunkttypen
|
| limits.h
|
Implementierungskonstanten
|
| locale.h
|
Länderspezifische Eigenschaften
|
| math.h
|
Mathematische Funktionen
|
| setjmp.h
|
Unbedingte Sprünge
|
| signal.h
|
Signale
|
| stdarg.h
|
Variable Parameterübergabe
|
| stddef.h
|
Standard-Datentyp
|
| stdio.h
|
Standard-I/O
|
| stdlib.h
|
Nützliche Funktionen
|
| string.h
|
Zeichenkettenoperationen
|
| time.h
|
Datum und Uhrzeit
|
Neu hinzugekommen beim C99-Standard (bzw. C95) sind dann noch folgende Headerdateien (nicht überall vorhanden):
Tabelle 12.2
Standard-Headerdateien, seit C99 vorhanden
| Headerdatei
|
Bedeutung
|
| complex.h
|
Komplexe Arithmetik (Trigonometrics, etc.)
|
| Fenv.h
|
Kontrolle der Gleitpunkzahlen-Umgebung
|
| inttypes.h
|
Für genauere Integertypen
|
| iso646.h
|
Alternative Schreibweisen für logische Operatoren; Zur Verwendung von Zeichensätze im ISO646-Format (seit C95 vorhanden)
|
| stdbool.h
|
Boolsche Datentypen
|
| stdint.h
|
Ganzzahlige Typen mit vorgegebener Breite
|
| tgmath.h
|
Typengenerische Mathematik-Funktionen
|
| wchar.h
|
Umwandlung von Strings zu Zahlwerten für den erweiterten Zeichensatz; String- und Speicherbearbeitung für den erweiterten Zeichensatz; Ein- und Ausgabe für den erweiterten Zeichensatz (seit C95 vorhanden)
|
| wctype.h
|
Zeichenuntersuchung für den erweiterten Zeichensatz (seit C95 vorhanden)
|
|