Include Guards
Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy — Lektion 2 von 61.
Wenn eine Header-Datei mehrmals in ein Projekt eingebunden wird, sieht der Compiler dieselben Deklarationen wiederholt, was zu Fehlern führt. Dies geschieht häufig, wenn mehrere Dateien denselben Header einbinden oder wenn Header sich gegenseitig einbinden. Include-Guards lösen dieses Problem.
Ein Include-Guard verwendet drei Präprozessor-Direktiven, um sicherzustellen, dass der Inhalt eines Headers nur einmal verarbeitet wird:
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int add(int a, int b);
#endif
So funktioniert es: #ifndef MATH_UTILS_H prüft, ob das Symbol MATH_UTILS_H noch nicht definiert wurde. Falls nicht, fährt der Präprozessor fort und definiert es sofort mit #define MATH_UTILS_H. Alles zwischen diesem Punkt und #endif wird in die Kompilierung einbezogen.
Beim zweiten Mal, wenn dieser Header eingebunden wird, ist MATH_UTILS_H bereits definiert, sodass der gesamte Block übersprungen wird. Der Name des Guards ist normalerweise der Dateiname in Großbuchstaben, wobei Punkte und Sonderzeichen durch Unterstriche ersetzt werden.
Jede Header-Datei, die Sie erstellen, sollte Include-Guards besitzen. Dies ist eine gängige Praxis, die Kompilierungsfehler verhindert und sicherstellt, dass Ihr Code von überall in Ihrem Projekt sicher eingebunden werden kann.
Aufgabe
EinfachLassen Sie uns eine Header-Datei vor doppelter Einbindung schützen, indem wir Include-Guards hinzufügen. Sie werden auf dem Begrüßungs-Utility aus der vorherigen Lektion aufbauen, aber dieses Mal sicherstellen, dass der Header sicher mehrfach eingebunden werden kann.
Sie werden zwei Dateien erstellen:
greet.h: Ihre Header-Datei, die die Funktionsdeklaration fürgreetenthält. Dieses Mal umschließen Sie den gesamten Inhalt mit Include-Guards unter Verwendung des SymbolsGREET_H.main.c: Ihre Hauptdatei, die den Header einbindet, die Funktiongreetimplementiert und sie vonmain()aus aufruft.
Die Funktion greet sollte einen const char* Parameter für den Namen akzeptieren und Folgendes ausgeben:
Hello, Alice!Ihre Header-Datei sollte dieser Struktur folgen:
#ifndef GREET_H
#define GREET_H
// function declaration here
#endifSie erhalten eine Eingabe: einen Namen (String).
Geben Sie die Begrüßungsnachricht genau wie im oben gezeigten Format aus, wobei Sie Alice durch den angegebenen Namen ersetzen.
Spickzettel
Include-Guards verhindern, dass Header-Dateien während der Kompilierung mehrmals verarbeitet werden, was zu Fehlern führen würde.
Ein Include-Guard verwendet drei Präprozessor-Direktiven:
#ifndef HEADER_NAME_H
#define HEADER_NAME_H
// Header-Inhalt hier
#endif
#ifndef prüft, ob ein Symbol nicht definiert wurde. Wenn es nicht definiert ist, definiert #define es und der Inhalt wird verarbeitet. Bei nachfolgenden Einbindungen ist das Symbol bereits definiert, sodass der gesamte Block übersprungen wird.
Der Name des Guards ist normalerweise der Dateiname in Großbuchstaben, wobei Punkte und Sonderzeichen durch Unterstriche ersetzt werden.
Jede Header-Datei sollte standardmäßig über Include-Guards verfügen.
Probier es selbst
#include <stdio.h>
#include "greet.h"
// TODO: Implementiere die greet-Funktion, die "Hello, <name>!" ausgibt
int main() {
char name[100];
scanf("%s", name);
// TODO: Rufe die greet-Funktion mit name auf
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Object Oriented Programming
1Grundlagen der modularen Programmierung
Header-DateienInclude GuardsQuelldateienStatische FunktionenWiederholung: Modularer Taschenrechner4Kapselung
Konzept der Opaque PointersOpaque Structs definierenGetter und SetterValidierung in SetternRückblick: Die geheime Box2Objekte und Methoden
Structs als ObjekteDer 'Self'-PointerConst-CorrectnessPointer vs. WertHilfsmethodenZusammenfassung: Point Manager5Projekt: Einfaches Bankkonto
Projekt-SetupImplementierung des Kontos3Objekt-Lebenszyklus
Konstruktor-MusterDestruktor-MusterStack-InitialisierungTiefe KopieRückblick: String-Wrapper6Vererbung durch Komposition
Struct-EinbettungDie First-Member-RegelZugriff auf Parent-MemberUpcastingRückblick: Formenhierarchie9Projekt: Formen-Zeichner
ProjektübersichtKreis-Implementierung