C-Header-Dateien verstehen: Typen, Verwendung und Best Practices
Sie fordern die Verwendung einer Header-Datei in Ihrem Programm an, indem Sie sie mit der C-Präprozessor-Direktive #include einbinden, wie Sie es bei der Einbindung der stdio.h-Header-Datei gesehen haben, die zusammen mit Ihrem Compiler geliefert wird.
Das Einbinden einer Header-Datei entspricht dem Kopieren des Inhalts der Header-Datei, aber wir tun dies nicht, da es fehleranfällig wäre und es keine gute Idee ist, den Inhalt einer Header-Datei in Quelldateien zu kopieren, besonders wenn wir mehrere Quelldateien in einem Programm haben.
Eine gängige Praxis in C- oder C++-Programmen ist, alle Konstanten, Makros, systemweiten globalen Variablen und Funktionsprototypen in Header-Dateien zu halten und diese Header-Datei dort einzubinden, wo sie benötigt wird.
Include-Syntax
Sowohl benutzerdefinierte als auch System-Header-Dateien werden mit der Präprozessor-Direktive #include eingebunden. Sie hat die folgenden zwei Formen:
#include <datei>
Diese Form wird für System-Header-Dateien verwendet. Sie sucht nach einer Datei namens 'datei' in einer Standardliste von Systemverzeichnissen. Sie können Verzeichnisse dieser Liste mit der -I-Option beim Kompilieren Ihres Quellcodes voranstellen.
#include "datei"
Diese Form wird für Header-Dateien Ihres eigenen Programms verwendet. Sie sucht nach einer Datei namens 'datei' im Verzeichnis, das die aktuelle Datei enthält. Sie können Verzeichnisse dieser Liste mit der -I-Option beim Kompilieren Ihres Quellcodes voranstellen.
Include-Operation
Die #include-Direktive funktioniert, indem sie den C-Präprozessor anweist, die angegebene Datei als Eingabe zu scannen, bevor er mit dem Rest der aktuellen Quelldatei fortfährt. Die Ausgabe des Präprozessors enthält die bereits generierte Ausgabe, gefolgt von der Ausgabe, die aus der eingebundenen Datei resultiert, gefolgt von der Ausgabe, die aus dem Text nach der #include-Direktive kommt. Wenn Sie beispielsweise eine Header-Datei header.h wie folgt haben:
char *test (void);
und ein Hauptprogramm namens program.c, das die Header-Datei verwendet, wie folgt:
int x;
#include "header.h"
int main (void) {
puts (test ());
}
wird der Compiler denselben Token-Stream sehen, als ob program.c folgendermaßen aussehen würde:
int x;
char *test (void);
int main (void) {
puts (test ());
}
Once-Only Header (Einmaliges Einbinden)
Wenn eine Header-Datei zweimal eingebunden wird, verarbeitet der Compiler ihren Inhalt zweimal, was zu einem Fehler führt. Der Standardweg, dies zu verhindern, besteht darin, den gesamten eigentlichen Inhalt der Datei in eine Bedingung einzuschließen, wie folgt:
#ifndef HEADER_DATEI #define HEADER_DATEI /* der gesamte Header-Datei-Inhalt */ #endif
Dieses Konstrukt ist allgemein als #ifndef-Wrapper bekannt. Wenn der Header erneut eingebunden wird, wird die Bedingung falsch sein, da HEADER_DATEI definiert ist. Der Präprozessor überspringt den gesamten Inhalt der Datei, und der Compiler sieht ihn nicht zweimal.
Computed Includes (Berechnete Includes)
Manchmal ist es notwendig, eine von mehreren verschiedenen Header-Dateien auszuwählen, die in Ihr Programm eingebunden werden sollen. Zum Beispiel könnten sie Konfigurationsparameter für verschiedene Betriebssysteme spezifizieren. Sie könnten dies mit einer Reihe von Bedingungen tun:
#if SYSTEM_1 # include "system_1.h" #elif SYSTEM_2 # include "system_2.h" #elif SYSTEM_3 ... #endif
Aber je mehr es wird, desto mühsamer wird es. Stattdessen bietet der Präprozessor die Möglichkeit, ein Makro für den Headernamen zu verwenden. Dies nennt man einen berechneten Include. Anstatt einen Headernamen als direktes Argument von #include zu schreiben, setzen Sie einfach einen Makronamen dort ein:
#define SYSTEM_H "system_1.h" ... #include SYSTEM_H
SYSTEM_H wird expandiert, und der Präprozessor sucht nach system_1.h, als ob #include ursprünglich so geschrieben worden wäre. SYSTEM_H könnte durch Ihr Makefile mit einer -D-Option definiert werden.
C Sprache
- C-Dateiverwaltung: I/O mit fopen, fprintf, fread & fseek meistern
- Python File I/O: Dateioperationen, Lesen, Schreiben und Verwaltung meistern
- Java-Dateioperationen mit java.io meistern – Erstellen, Lesen, Schreiben & Löschen
- STL-Dateien verstehen: Das Rückgrat des 3D-Drucks
- Datei-E/A in Verilog meistern: Öffnen, Lesen, Schreiben und Schließen
- Datei-I/O in C meistern: Erstellen, Öffnen & Verwalten von Dateien
- C++ Datei-I/O: Lesen & Schreiben mit fstream
- C# Datei-E/A: Lesen, Schreiben & Stream-Verwaltung
- Python Datei-E/A: Eingabe- und Ausgabeoperationen meistern
- Dreikantfeile: Aufbau, Anwendung und Pflege