Hallo! Wie lagere ich denn Funktionen in Header-Dateien aus? Muss ich die Prototypendeklaration in der Header mit den Funktionen oder im Hauptfile angeben? Gruß Markus
Hallo Markus, ich habe es immer folgendermasen gemacht. Ein seperates Headerfile erstellen. Deine Funktion z.B. "int xxx (int z,int y)" schreibst Du auch in dieses Headerfile "extern int xxx (int,int);" somit ist diese bekannte nun bindest Du dieses Headerfile in Deinem main Programm mit #include <HEADERFILE.h> ein. Nun solltest Du Deine Funktion aus main aufrufen können. TOM
Hi Tom! Muss ich im Main den Prototyp auch noch einmal deklarieren oder reicht das im Header? Wie mache ich es mit den Variablen und/oder LookUpTables die ich für das Unterprogramm verwende? Sie werden auch im Hauptprogramm verwendet.
Den Prototypen deklarierst Du im Headerfile. Und dieses Headerfile #include -st Du dann dort wo dus brauchst, zb. im main(). Das Grundprinzip ist doch folgendes in C: Jedes Source Code file wird fuer sich alleine vom Compiler uebersetzt. Und in jeder dieser Source Code Einheit muss alles deklariert sein, was der Compiler nicht von sich aus kennt. Natuerlich kannst Du auch komplett auf den Header pfeifen und in jedem Source Code die Dinge einzeln deklarieren. Etwa so: File1.c ****** int foo( int bar ); void foo2() { int j = foo( 5 ); } File2.c ******* int foo( int bar ); void foo3() { int k = foo( 7 ); } Main.c ****** int foo( int bar ); void foo2( void ); void foo3( void ); int main() { int l = foo( 8 ); foo2(); foo3(); } aber Du merkst schon, wo das hinfuehrt: Wenn Du foo() anederst, zb indem ein zusatzlicher Parameter mit aufgenommen wird, so musst Du die Aenderung in diesem Fall an 4 Stellen machen: 1) foo selbst 2) den Prototypen in File1.c 3) den Prototypen in File2.c 4) den Prototypen in Main.c Das das bei vielen Funktionen und vielen Files mehr als fehleranfaellig ist, brauchen wir wohl nicht zu diskutieren. Dazu gibt es aber in C den Mechanismus des #include Bevor sich der Compiler den eigentlichen Programtext vornimmt, rauscht der erstmal durch den Praeprozessor. Der ersetzt alle Zeilen mit #include <Dateiname> durch den aktuellen Inhalt der Datei namens 'Dateiname'. Du schreibst also zb. Foo.h ***** int foo( int bar ); File1.c ******* #include "Foo.h" void foo2() { int j = foo( 5 ); } File2.c ******* #include "Foo.h" void foo3() { int k = foo( 7 ); } Uebersetzt du zb. File1.c, dann passiert Folgendes: Zuerst nimmt sich der Praeprozessor den Text vor und ersetzt die Zeile #include "Foo.h" mit dem Inhalt der Datei 'Foo.h'. Als Ergebnis erhaelt er: int foo( int Bar ); void foo2() { int j = foo( 5 ); } und erst dieses Ergebnis wird durch den tatsaechlichen C Compiler gejagt. Der ist natuerlich happy damit, denn in der Funktion foo2() wird eine andere Funktion foo() benutzt und deren Protoyp wurde ja korrekt angegeben. Aber: Aendert sich an der Funktion foo() etwas, dann aenderst Du einfach nur an einer einzigen Stelle den Protoypen: in Foo.h alle anderen, File1.c File2.c und Main.c kriegen das automatisch mit, da sie ja Foo.h inkludieren und somit die Aenderung beim Compilieren mitkriegen. Variablen/Lookup Tabellen. Im Prinzip machst Du genau das gleiche, nur kommt Dir hier die ODR (One Definition Rule) in die Quere. Jedes Teil darf nur einmal definiert werden! Bei einem Protoypen weiss der Compiler auch so, dass es sich um einen Prototypen handelt. Etwas in der Form int foo( int bar ); kann nur ein Protoyp (also eine Deklaration) sein. Eine Definition wuerde ganz anders aussehen int foo( int bar ) { /* Implementierung von foo */ } bei globalen Variablen ist das aber anders. Ist int Global1; nun eine Definition oder eine Deklaration. Antwort: Es ist eine Definition. Wenn Du sowas in Foo.h stehen haettest, dann wuerde der Compiler klarerweise beim Uebersetzen von File1.c eine Variable namens Global1 anlegen. Dasselbe wuerde er aber auch machen, wenn File2.c und Main.c uebersetzt werden. Das geht aber nicht, denn dann wuerde der Linker 3 Variablen namens Global1 sehen und nicht wissen, welche denn dir Richtige ist. Also muss man das anders machen: Die Definition muss zu einer Deklaration werden: Foo1.h ****** int foo( int bar ); extern int Global1; Damit wissen alle *.c Bescheid, dass es irgendwo eine Variable namens Global1 gibt und das diese vom Typ int ist. Soweit so gut. Aber irgendwo muss diese Variable auch tatsaechlich existieren, sonst koennte der Linker sie nicht finden. Na zb. hier: Main.c ****** #include "Foo.h" int Global1; /* da ist sie. Die Variable 'Global1' Alle anderen die Foo.h inkludieren wissen nur dass es sie gibt. Aber hier ist sie tatsaechlich */ int main() { Global1 = 5; }
Echt ne richtig schöne ausführliche Antwort, da hatte wohl schon jemand einen zuviel getrunken und konnte sich aufgrund des Alkoholgehaltes im Blute wohl nicht mehr zusammenreißen und musste alles schreiben was er zu diesem Thema wusste und dann auch noch so, dass man es ohne große Kenntnisse verstehen kann :). Es sollte an jedem Tag Karnevalanfang sein, dann würde es hier bestimmt öfters solche schönen ausführlichen Antworten geben...einfach klasse :)
Schau mal in die Codesammlung. Dort gibt es einige Beiträge von Peter Dannegger. In diesen sind meist Zip-Dateien zu finden, die komplette Projekte enthalten. Dort kann der C-Interessierte sehen, wie man strukturierte Programme schreibt. Dort sieht man auch, was in den Header gehört und was in die Programmdatei. Mir persönlich ist das zwar etwas zu hoch (ich kann kein C), aber wer C auf AVR oder 51er lernen will, der kann sich da 'ne Menge abschaun. Ist jedenfalls besser, als hier herumzuattern und nix zu verstehen. Gruß und Bit- & Bytebruch... ...HanneS...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.