Eigene Header und Module
-
Ich habe jetzt mehrere Bücher gelesen, aber irgendwie waren das wohl alle nicht die richtigen. die Frage die bei mir noch offen ist: Was genau schreibt man in die .h und was genau in die .c datei?
Ich denke jetzt in die .h kommen die ganzen deklaration der structs usw und in die .c dann die funktionen die darauf operieren. sehe ich das richtig?
vielleicht hat ja jemand für mich ein kleinen beispielcode parat oder kann es mir etwas besser erklären ^^ *need help*
-
In den Header schreibst du neben deinen Typen (z.B. structs) und vielleicht einigen Makros auch die Prototypen deiner Funktionen, die Implementation kommt dann in die .c-Datei.
-
vielleicht hat ja jemand für mich ein kleinen beispielcode parat oder kann es mir etwas besser erklären
Die gute alte Freundin weiß immer weiter:
http://en.wikipedia.org/wiki/Header_file
-
danke für eure schnelle antworten.
_matze schrieb:
In den Header schreibst du neben deinen Typen (z.B. structs) und vielleicht einigen Makros auch die Prototypen deiner Funktionen, die Implementation kommt dann in die .c-Datei.
sind makros denn ANSI standard?
bgdnoy schrieb:
vielleicht hat ja jemand für mich ein kleinen beispielcode parat oder kann es mir etwas besser erklären
Die gute alte Freundin weiß immer weiter:
http://en.wikipedia.org/wiki/Header_fileint add(int, int); int triple(int x){ return add(x, add(x, x)); }
wozu deklariert man funktionsprototypen? is das nicht unnötige arbeit?
-
TTP schrieb:
wozu deklariert man funktionsprototypen? is das nicht unnötige arbeit?
Damit der Compiler mit Forward- Declarations fertig wird. Also, Du bindest eine Funktion ein (rufst sie in der Source auf), bevor der Compiler sie geparst hat.
Da die Compiler heute fast alle Multipass arbeiten, fast unnötig, aber immer noch nettes Mahnmal für QuickChanges. Ich setze die Prüfung auf Prototypes zumindest auf aktiv, dann denk' ich wenigstens noch ein paar Sekunden drüber nach.
-
wozu deklariert man funktionsprototypen? is das nicht unnötige arbeit?
Und wenn du ein C-File vor ein paar Tagen übersetzt hast, und heute noch eines übersetzen willst, das auf Funktionen aus dem alten zugreift, musst du das alte nicht nochmals mitübersetzen. Es reicht dann, das neue zu übersetzen und die beiden Objektdateien zusammen zu linken. Für das Übersetzen des neuen C-Files muss der Compiler aber die Prototypen der Funktionen kennen, die du aus dem alten aufrufst: sonst kann er nicht arbeiten.
Das hat mehrere angenehme Vorteile, einer ist, daß man Übersetzungs-Zeit spart.
Siehe auch:
http://en.wikipedia.org/wiki/Object_file
http://en.wikipedia.org/wiki/LinkerEDIT:
sind makros denn ANSI standard?
Ja.
-
cool, danke für eure antworten. glaube jetzt hab ich es gepeilt...
hat jemand ne idee wieso structs in meinen headern funktionieren, aber in einer header-datei nicht?
ich erhalte bei Visual Studio
Fehler 3 error C2011: 'urliste': 'struct' Typneudefinition f:\team-builder\team-builder\tbgrp.h 1 Team-Builder
struct urliste { char name[MAXS]; //Nachname int w; //Absprungwahrscheinlichkeit float note; //Stärke struct wunsch *person; //Wunsch --> Abneigung oder Zuneigung struct urliste *next; //Zeiger auf Nachfolger }; //typedef stuct uliste urliste;
das ist der code, mehr steht da gar nicht drin... ich peil nicht woran das liegen kann...
wenn ich in einer .c-Datei eine andere Headerfile brauche, dann kann ich die doch da auch einfach includen oder? Wenn ich die nämlich nicht angebe bekomm ich immer die Warnung "Function not intern, searching extern"
Edit: hab das typedef schon extra kommentiert, wenn ich es auskommentiere bekomm ich auch ne fehlermeldung? o.O
2nd Edit: Nehm ich den #include raus, dann bekomm ich folgenden Fehler:
Fehler 6 error LNK2005: _lread ist bereits in tbio.obj definiert. team-builder.obj Team-Builder
-
Ganz allgemein steckt kein bißchen Zauberei hinter einem
#include
.
Das wird einfach durch den Inhalt der Datei ersetzt.So kann's ganz leicht passieren, daß du ein .h-File mehrmals drinnen stehen hast, und dann gibt's eben eine Neudefinition.
So, jetzt zum Thema: ich hab keine Ahnung von Visual Studio, und kann deshalb nicht sagen, ob das mit dem oben erwähnten zusammenhängt.
Was ich dir aber sagen kann, ist dass die MeldungFehler 6 error LNK2005
eine Meldung vom Linker ist (weil's die Objektdateien betrifft).
Da ist das Übersetzen gut gegangen, aber der Linker hat scheinbar nachher einen Namenskonflikt oder sowas.Versuch's jedenfalls mal mit Include Guards, dann kannst du foo.h inkludieren, so oft du willst. Sollte den Fehler eingrenzen.
[edit: Link ging ins Leere]
-
hab´s problem anscheind gelöst...
man braucht in vs die .c - Dateien nicht includen.... (Dachte das muss man auch, weil in den .h-Dateien ja keine Referenz zu denen besteht)...
Danke, aber ich werd das Include Guards auch umsetzten
-
man braucht in vs die .c - Dateien nicht includen
Nö, das sollte man nirgendwo machen.
-
TTP schrieb:
hab´s problem anscheind gelöst...
man braucht in vs die .c - Dateien nicht includen.... (Dachte das muss man auch, weil in den .h-Dateien ja keine Referenz zu denen besteht)...
Danke, aber ich werd das Include Guards auch umsetzten
Man muss bzw. darf keine .c-Dateien einbinden, weil der Compiler beim Übersetzen nicht die tatsächliche Implementation einer Funktion (einer anderen Übersetzungseinheit), die du aufrufen willst, braucht (die braucht dann der Linker). Er muss sie einfach nur kennen, und das regelst du über den Prototypen, der in dem Header steht, den du inkludierst. Der Linker fügt dann die verschiedenen Objektdateien (deine kompilierten .c-Dateien) zusammen. Inkludierst du nun aber einer .c-Datei, wurde diese zwei mal übersetzt und du bekommst eine Meldung "xxx ist bereits in xxx.obj definiert". Daher brauchst du einfach nur den Header inkludieren. Und um hier doppeltes Inkludieren zu verhindern, benutzt man include guards.
-
achso... wieder was dazu gelernt
in visual studio klappt das compilieren ja jetzt, bei linux bin ich gerad mit makefile und co am verzeifweln, aber ich glaub dazu mach lieber ma n anderen thread auf, da klappt irgendwas beim linken nicht...