Verknüpfen .h-Dateien mit .c mit #ifdef-header-guards
im Probleme verknüpfen .h und .c-Dateien, das habe ich auch gelesen, einige threads zu diesem problem und alle von Ihnen ist etwas vage und noch immer kann ich nicht begreifen, das Konzept von es, und ich habe eine Menge der Verlinkung Probleme, Sagen, ich habe b.c-und b -.h, die ich verwenden in einem.c, und ich bin verwirrt, ob b.h beide ein.c-und b -.c cuz b.c selbst muss wissen, die Struktur definiert in b ist.h, ich habe einige Funktion, die hat Ihr Vorbild in b ist.h und ist in b.c, die auch die Struktur in b ist.h, im bin nicht mit b.h in b ist.c cuz, was ich wissen b.h ist mehr wie eine Schnittstelle zu einer.c, die die Funktionen in b haben.c... Hier ein klarer Beispiel
b.h-Datei
typedef struct{
int x, y;
}myStruct;
void funct1(myStruct);
void funct2(myStruct);
b.c-Datei
void funct1(myStruct x)
{
//do something
}
void funct2(myStruct y)
{
//do something
}
ein.c-Datei
#include "b.h"
int main()
{
myStruct x;
funct1(x);
funct2(y);
return 0;
}
Ausgeführt wird der Befehl in cygwin: gcc b.c ein.c -g
Nun der verwirrende Teil, ich habe eine Verknüpfung Fehler, worin, wenn b ein.c compiliert es nicht erkennen kann, die Struktur und die Prototypen in b ist.h. Cuz alle ich weiß ist, dass b ist.h wird verwendet, um den link b.c aus ein.c, aber wenn die beiden .c kompiliert, es scheint, dass b.c kann nicht finden, Ihre Verteilung und Prototypen,
Warum habe ich nicht: b.h in b ist.c?
Antwort: Cuz, was ich wissen, b ist.h ist bereits enthalten.c und wenn ich es wieder in b.c, ich werde tun, Doppel-Einschlüsse <--- das ist, was ich lernen so weit und ich weiß, es ist #ifdef, aber es scheint funktioniert es nicht, vielleicht, ich weiß noch nicht, wie es zu benutzen, wenn Sie wissen, fühlen Sie bitte sich frei, dies zu diskutieren.
Wenn Sie eine Idee haben, wie man über das fühlen Sie sich frei, mir zu sagen einige.
gibt es eine #ifdef-Direktive, aber ich kann nicht scheinen, um eine Idee, wie dies zu tun.
HINWEIS: nehmen Sie an, DASS ALLE OBEN genannten CODES IST SYNTAKTISCH KORREKT, wenn es alle falsch geschriebenen Wort bitte ignorieren, ich bin nur nach der Einschlüsse zwischen .h und .c
InformationsquelleAutor lemoncodes | 2013-01-12
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sie wirklich brauchen, um
#include b.h
imb.c
. Jede Datei wird separat kompiliert werden, bevor der linker übernimmt, so spielt es keine Rolle, dass Sie b.h in ein.c, weil b.c kompiliert wird, indem Sie selbst und hat keine Ahnung über den Inhalt von b ist.h, es sei denn, Sie zählen es.Hier ist ein Beispiel für eine
#include
guardWenn some_header_file.h enthalten ist, überall, alles in zwischen den
#ifndef
und die#endif
wird ignoriert, wenn SOME_HEADER_FILE_H definiert wurde, was auf das erste mal, es ist enthalten in der compilation unit.Es ist gängige Praxis, um den Namen des
#define
nach dem Namen der Datei, um sicherzustellen, Einzigartigkeit in Ihrem Projekt. Ich mag Präfix mit dem Namen von meinem Projekt oder namespace als auch, um zu reduzieren das Risiko von Kollisionen mit anderen code.HINWEIS: Die gleiche header-Datei aufgenommen werden KÖNNEN mehrere Male in Ihrem Projekt auch mit den oben genannten include-guard, nur es kann nicht aufgenommen werden zweimal in der selben compilation unit. Dies zeigt sich wie folgt:
Nun wollen wir sehen, was passiert, wenn wir versuchen, die beiden oben genannten Dateien. In einer einzigen compilation unit:
Dieser erzeugt einen compiler-Fehler, da test2 ist nicht definiert - es wird ignoriert, in header2.h weil HEADER_H ist bereits definiert durch die Zeit enthalten ist. Wenn wir nun die einzelnen header, die in separaten Zusammenstellung Einheiten:
Kompiliert er fein und erzeugt die erwartete Ausgabe (1 und 2), obwohl wir zwei Dateien, die beide define HEADER_H.
#ifndef
bedeutet wenn nicht definiert und wohin Sie gehören .h, er definiert das symbol, so, wenn Sie die gleiche .h wieder, das symbol ist bereits definiert.Nein, darunter b.h in ein.c hat keine Wirkung auf b.c. Wenn b.h ist enthalten in b.c zum ersten mal
SOME_HEADER_FILE
definiert ist, innerhalb der b.c nur. Nachfolgende#ifdef
und#ifndef
Anweisung fürSOME_HEADER_FILE
innerhalb b.c kann dann erkennen Sie es in b ist.c.ohh ich bekomme dein Punkt, hehe es gibt so viele Antwort-Regie an der gleichen Stelle, so werde ich nur die gleiche Frage, "hmmm, was ich meinte, ist, dass Ihr SOME_HEADER_FILE_His in einem .h Dateien richtig?, also, wenn das .h-Dateien enthalten ist, in, sagen, eine.c, und wieder enthalten in b.c, kann es Mangels B_H_INCLUDED ist laready definiert?"
Ich bearbeitet meine Antwort zu erklären, Remy ' s point weiter (eigentlich war ich schon mitten in dem schreiben, bevor ich es bemerkt in seinem Kommentar).
InformationsquelleAutor JBentley
Müssen Sie
b.h
in allen Dateien verwendet, die Strukturen, die definiert sind inb.h
. So muss eine#include <b.h>
in beiden Dateien. Um zu vermeiden, dassb.h
geladen ist mehrere Male, müssen Sie die Richtlinien#ifdef
. In deinem Fall:b.h
b.c:
Yeap. Die Richtlinie
#define B_H
definiert, dass die variable definiert ist. Also, wenn ein#ifndef
Suche nach B_H, wird false zurückgegeben und überspringen Sie den code, bis#endif
. Es ist wichtig, dass die variable B_H definiert ist, in nur einer.h
- Datei.hmm, ich sehe, ich bekomme dein Punkt
Ihre "Yeap", ist falsch. Wenn b.h ist enthalten in einem.c, b.c kann nicht erkennen, dass. B. h in b ist.c so B_H kann definiert werden, innerhalb b.c.
ich glaube, @WilliamSeitiMizuta habe meine Punkte ich Rede nicht von b ist.h ich spreche B_H, die in b liegt.h
InformationsquelleAutor William Seiti Mizuta
Richtige Codierung hätte Sie beinhalten b.h in b ist.c.
Hier ist ein header-guard, die funktionieren sollte:
Setzen Sie Ihre Erklärungen, wo der Kommentar steht, und gehören überall müssen Sie.
BEARBEITEN
Die Art, wie ich es verstehe, ist, dass
gcc
kompiliert.b.c Erstens, weil ein.c hängt von b ist.c. Aber wenn es kompiliert.b.c zuerst b.h wurde noch nicht aufgenommen.Aber... die header-Datei muss eingebunden werden in der compile-Schritt, was geschieht, bevor der link-Schritt.
Ja, alles was zählt, ist die aktuelle Zusammenstellung Einheit (dh Sie nicht wollen, zu sein, einschließlich der gleichen Datei zweimal innerhalb der gleichen Einheit).
ohhh also, wenn das der Fall ist, können andere .c-Datei erkennen, die, Sagen wir in deinem Beispiel, B_H_INCLUDED wenn das bereits vorhandene?
Nicht sicher, was genau Sie Fragen in Ihrem Kommentar, ich denke, die Antwort ist ja... ich bin kein C-Experte (nur mache es für 2+ Jahre!).
InformationsquelleAutor BenjiWiebe
Müssen Sie
#include
b.h in b ist.c. Es ist nicht nur eine Schnittstelle für einen.c, b.c muss wissen, die gleichen Definitionen, die für seinen eigenen code sowie. Ihr Grund für die nicht inklusive b.h in b ist.c ist falsch. Jeder .c-Datei kompiliert wird getrennt von allen anderen .c-Datei. Wenn der compiler fertig ist, mit ein.c, beginnt es von neuem mit b.c. Es geht nicht darum, dass ein.c enthalten.b.h, denn b ist.c hat kein Konzept, dass einen.c noch vorhanden ist. Der Zweck eines header-guard zu verhindern .h-Datei verarbeitet, wiederholen Sie mal, wenn es mehrere Male während des kompilieren eines gegeben .c-Datei. Ohne die Wache, Erklärungen bekommen würde, kompiliert mehrere Male, was zu Fehlern führt über mehrere Deklarationen der bestehenden Symbole.InformationsquelleAutor Remy Lebeau