In einem nächsten Schritt wollen wir uns nochmal anschauen, was genau Module sind,
wie diese mit Symbolen zusammenhängen und was passiert, wenn man mehrere Module miteinander
bindet.
Dafür fangen wir zunächst einmal mit der Schnittstellenbeschreibung eines Moduls an.
Diese besteht aus einer H-Datei.
In der H-Datei steht beschrieben, was das Modul alles exportiert.
In dem Beispiel mit der Datei bar.h sehen wir einmal eine Funktionsdeklaration der Funktion
bar, die ein Integer als Argument erwartet und keinen Rückgabewert hat.
Was noch in einer H-Datei stehen kann, ist zum Beispiel die Bekanntmachung externer globaler
Variablen.
Ebenfalls können Typdefinitionen vorkommen.
Was hier nun vielleicht ein bisschen hervorsticht, sind die verwendeten Präprozessoranweisungen.
Wir haben ein if not def, ein define und ein end if.
Dies ist ein sogenannter include guard.
Damit wird sichergestellt, dass der Inhalt der Datei nur ein einziges Mal inkludiert
wird, auch wenn in der entsprechenden C-Datei, in der das include steht, dieses mehrfach
genannt wird.
Dies ist wichtig, weil einige Dinge, die in einer H-Datei stehen, nur ein einziges Mal
deklariert werden dürfen.
Bei Funktionsdeklaration ist das jetzt kein Problem, diese dürfen beliebig oft vorkommen,
solange sie sich nicht gegenseitig widersprechen, aber bei Strukturdefinition ist das wichtig,
dass diese jeweils nur ein einziges Mal definiert werden.
Als nächstes haben wir die Datei main.c.
Hier wird die main-Funktion definiert und außerdem soll das Modul bar verwendet werden.
Um das Modul nun zu verwenden, müssen wir einmal dessen Schnittstelle inkludieren.
Dies funktioniert hier mit der Präprozessoranweisung include bar.h.
Damit wird die bar.h-Datei inkludiert.
Was damit passiert, ist, dass die Funktionsdeklaration von bar bekannt gemacht wird.
Dementsprechend können wir nun in der main-Funktion bar mit dem Integerwert 42 aufrufen.
Am Anfang der Datei main sehen wir zwei verschiedene Includes.
Diese unterscheiden sich anhand der Zeichen, die die Namen der H-Datei umgeben.
Bei stdio handelt es sich um spitze Klammern, während bar.h von doppelten Anführungsstrichen
umgeben ist.
Die spitzen Klammern bedeuten, dass hier eine Datei auf dem globalen Suchpfad verwendet
wird.
Das ist ein vor definierter Pfad, auf dem alle Header-Dateien von installierten Bibliotheken,
wie eben der Standard-Bibliothek, zu finden sind.
Die doppelten Anführungsstriche hingegen bedeuten, dass hier eine Datei inkludiert
werden soll, die sich nicht im globalen Pfad befindet.
Gibt man beim Aufruf des Übersetzers zum Kompilieren der main.c-Datei keine weiteren
Optionen mit, wird unterstellt, dass sich die Datei bar.h im selben Verzeichnis befindet.
Ist das Modul jedoch unter einem anderen Pfad im Dateisystem verfügbar, so muss man diesen
Pfad dem Übersetzer bekannt machen, indem man die Option binnen Strich groß i gefolgt
von dem Pfad setzt.
Wichtig ist hierbei, dass das große i und der Pfad nicht durch ein Leerzeichen getrennt
sind.
Anschließend kann der Übersetzer bzw. der Präprozessor den Standard-Pfad und alle zusätzlich
angegebenen Pfade nach den notwendigen Header-Dateien durchsuchen.
Und damit kommen wir zu Symbolen, denn jede globale Variable und jede Funktion hat ihren
eigenen symbolischen Namen, über den auf sie zugegriffen wird.
Zugänglich über
Offener Zugang
Dauer
00:07:13 Min
Aufnahmedatum
2020-12-14
Hochgeladen am
2020-12-14 09:29:57
Sprache
de-DE