Datum:
Hallo Ich möchte mein Source file thematisch in mehrere Sourcefiles aufsplitten, ich erhalten stänig Fehlermeldungen und hab jedoch Mühe, welche Angaben ins .h und welche ins .c-File kommen. Ich versteh das ich das mit den Direktiven (insbesondere mit #ifndef ..#endif und #include) nicht. Konkret hab ich die Files menu.c, menu.h darin sind u. a. 2 structs definiert.
typedef struct A { struct *B; ... } A; |
und
typedef struct B { struct *A; uint8_t var; ...} B; |
Ich brauche also eine forward declaration. Soll die ins header-file? Brauche ich im .h-File #ifndef ..#endif Direktiven? Und wo muss ich die #include <avr/io.h> Direktive (für die Definition des uint8_t-Datentyps) einfügen? Der Variablentyp wird natürlich dann auch noch in anderen .c files verwendet. lcd.c, lcd.h ist es sinnvoll Definitionen von Konstanten wie #define LCD_RS PD5 im lcd.c, lcd.h oder gar im main.c zu definieren? main.c, main.h wie muss ich nun die menu.h und lcd.h (oder die files menu.c und menu.c?) in die main.c (oder main.h?) einbinden? Bin sehr froh um eure Hilfe Makrus
Datum:
... an den Struct-Definitionen liegts nicht, die heissen nämlich korrekt (nicht wie im vorigen Beitrag):
typedef struct A { struct B *structTyp1; ... } A; |
typedef struct B { struct A *structTyp2; uint8_t var; ...} B; |
Datum:
Markus schrieb: > Ich brauche also eine forward declaration. Soll die ins header-file? Ja. > Brauche ich im .h-File #ifndef ..#endif Direktiven? Nicht wirklich, ist aber eine gute Idee -> machen. > Und wo muss ich die > #include <avr/io.h> Direktive (für die Definition des uint8_t-Datentyps) > einfügen? Ins .c file. Jedes .c file muss sich ohne Fehler/Warnungen compilieren lassen (also nicht den Linker anwerfen, nur object erzeugen). Im .c file holst du dir das zugehörige header file rein (include), damit prüfst du auch immer die Konsistenz.
Datum:
Markus schrieb: > menu.c, menu.h > darin sind u. a. 2 structs definiert. >
> typedef struct A { struct *B; ... } A; > |
> und >
> typedef struct B { struct *A; uint8_t var; ...} B; > |
> > Ich brauche also eine forward declaration. Soll die ins header-file? Es ist ganz einfach. Schau dir dein Header File an. Nur dieses eine Header File. Lies es von oben nach unten. Welche Begriffe kommen vor, die nicht Bestandteil der Sprache C sind (wie zb typedef ja ein Schlüsselwort ist). Für alles, was nicht in diesem Sinne Bestandteil von C ist, brauchst du eine Form der Deklaration ehe du diesen Begriff dann tatsächlich verwenden kannst. Verwenden im Sinne von: diesen Begriff zur Definition von Variablen benutzen, Memberzugriffe in Strukturen etc. Jetzt gibt es 3 Möglichkeiten * entweder du kannst einfach die Reihenfolgen der Deklarationen tauschen * oder das was du benötigen würdest ist in einem anderen Header File, dann kommt ein entsprechender #include rein * oder du brauchst eine Forward Deklaration. Eine Forward Deklaration sagt dem Compiler: "Hör mal, das Teil gibt es. Ich hab da keinen Tippfehler gemacht. Ich kann dir zwar jetzt keine Details nennen, aber eine Struktur dieses Namens existiert tatsächlich". So eine Forward Deklaration ist gut genug, dass man zb einen Pointer auf eine STruktur machen kann. Denn wie groß ein Pointer sein muss das weiß der Compiler. Was er aber nicht weiß: Ob du dich vertippt hast, und die Struktur in Wirklichkeit ganz anders heißt. Mit einer Forward Deklaration behebst du dieses Wissens-Manko des Compilers. > Brauche ich im .h-File #ifndef ..#endif Direktiven? Das kommt drauf an. Meistens braucht man sie nicht wirklich. Da es sich aber nicht lohnt darüber groß nachzudenken, macht man einfach überall Include Guards rein. Ist eine Sache auf 5 Sekunden und geht schneller als sich groß den Kopf über die Notwendigkeit zu zerbrechen. > Und wo muss ich die > #include <avr/io.h> Direktive (für die Definition des uint8_t-Datentyps) dort wo du sie brauchst. verwendest du uint8_t? Wenn ja, dann brauchst du einen include auf stdint.h (wird von avr/io.h reingezogen. avr/io.h ist fein, inkludiert aber eigentlich schon etwas zu viel. Du kaufst dir ja auch nicht einen 3-er BMW, weil dir die BMW-Parkscheibe so gefällt. Kaufst du einen, kriegst du eine Parkscheibe mit dazugeliefert. Aber die Parkscheibe haben zu wollen ist kein Grund einen 3-er zu kaufen.) > ist es sinnvoll Definitionen von Konstanten wie #define LCD_RS PD5 im > lcd.c, lcd.h oder gar im main.c zu definieren? Das kommt drauf an, was mit diesen Konstanten bezweckt wird. Wird diese Konstante nur im C File verändert und hat keine Konfigurationswirkung, dann sollte sie auch nur im C-File sein. Gehört diese Konstante auch im weitesten Sinne zur 'äusseren Schnittstelle' des C-Files, dann gehört sie ins Header File. > wie muss ich nun die menu.h und lcd.h (oder die files menu.c und > menu.c?) in die main.c (oder main.h?) einbinden? mit einem include
Datum:
Und noch ein Link http://www.mikrocontroller.net/articles/Include-Files_(C) und dann auch noch die >>>FAQ<<< speziell Kapitel 6 und 7
Datum:
Markus schrieb: > menu.c, menu.h > darin sind u. a. 2 structs definiert. Wo jetzt, im menu.c oder menu.h? >
> typedef struct A { struct *B; ... } A; > |
> und >
> typedef struct B { struct *A; uint8_t var; ...} B; > |
> > Ich brauche also eine forward declaration. Soll die ins header-file? Die forward declaration wird für die Deklaration der structs benötigt. Also muss es auch dahin, wo die structs deklariert werden. Es macht keinen Sinn, eine forward declaration irgendwo in einen Header zu packen, wenn die eigentlichen Deklaration nicht auch dort sind. > Brauche ich im .h-File #ifndef ..#endif Direktiven? Musst du wissen. Es ist aber üblich, den kompletten Inhalt einer .h-Datei in ein ifdef einzuschliessen in der Form:
#ifndef MEINHEADER_H #define MEINHEADER_H ... #endif |
Dabei ist MEINHEADER_H ein Symbol, das nur in dieser Datei vorkommt. Das sorgt dafür, dass der Inhalt ignoriert wird, falls der Header mehrmals in der selben Datei inkludiert wird. > Und wo muss ich die > #include <avr/io.h> Direktive (für die Definition des uint8_t-Datentyps) > einfügen? uint8_t wird (wie auch die anderen Standard-Typen) in stdint.h definiert. Und ein #include muss an den Anfang der Datei, in der es gebraucht wird. > lcd.c, lcd.h > ist es sinnvoll Definitionen von Konstanten wie #define LCD_RS PD5 im > lcd.c, lcd.h oder gar im main.c zu definieren? Musst du wissen. Das #define ist nur dort wirksam, wo es im Text steht. Wird es in mehreren .c-Dateien gebraucht, dann muss es in eine .h-Datei, die von allen diesen .c-Dateien inkludiert wird. > main.c, main.h > wie muss ich nun die menu.h und lcd.h (oder die files menu.c und > menu.c?) in die main.c (oder main.h?) einbinden? Mit #include… Und eine .c-Datei wird nicht inkludiert, Punkt. Für einen Anfänger kann der letzte Satz ruhig als Dogma so stehen bleiben.
Datum:
@Karl Heinz Buchegger: der Link ist leider nicht angekommen. ok, vielen dank, hab jetzt einige fehler ausräumen können (insbesondere die beiden #include <stdio.h>, #include <avr/io.h> haben natürlich Konflikte verursacht:)
Datum:
Markus schrieb: > @Karl Heinz Buchegger: der Link ist leider nicht angekommen. Ah. Das ist die Forensoftware. Klick auf den Link, und ergänze dann händisch in der Adressleiste deines Browsers die fehlende ")" im Text von "(C)" Dann klappts auch mit dem Link