Forum: Mikrocontroller und Digitale Elektronik Unterschied zwischen header- und source-datei


von Sebastian D. (bineuling)


Lesenswert?

Hallo allerseits,

Ich bin gerade dabei von assembler auf c umzusteigen. Jetzt tun sich da 
einige Fragen auf die leider noch keine Antwort gefunden haben. Ich habe 
mich auch schon mit dem (sehr hilfreichen) C-Tutorial welches hier 
angeboten wird beschäftigt. Da steht jedoch nichts über die 
grundsätzliche Struktur eines c-programms. Lange Rede kurzer Sinn: 
Welchen Teil vom Code muss ich in die header bzw source datei packen ?. 
Ich habe in Codebeispielen nämlich schon unterschiedliche Varianten 
gesehen.

1. Header: Nur Deklarationen
2. Header: Funktionsblöcke (z.B: LCD-Treiber)

Anscheinden funktionieren beide Varianten. Jedoch gibt es doch bestimmt 
eine Regel wie man es machen sollte.

Um konkret zu werden: Ich habe ein Projekt am laufen in dem ein 
Controller die Temperatur per externem Sensor via Analogeingang misst 
und auf einem Display darstellt. Da das Gerät per AAA-Akku betrieben 
wird soll desssen Spannung über den Controllerinternen (Atmega88) 
Komparator überwacht werden. Beim Unterschreiten der Minimalspannung von 
1.0V soll eine Interruptroutine ablaufen und eine Meldung ausgegeben 
werden.
Nun weiß ich wie ich die Programmteile schreiben werde, aber nicht wo 
sie hingehören.

Ich wäre sehr dankbar für Antworten zu diesem grunsätzlichen Thema.

bye

von Johannes M. (johnny-m)


Lesenswert?

Sebastian Deubl wrote:
> 1. Header: Nur Deklarationen
Korrekt!

> 2. Header: Funktionsblöcke (z.B: LCD-Treiber)
Nein. In eine Headerdatei (*.h) gehören keine Funktionsdefinitionen! 
Die kommen in eine entsprechende .c-Datei, die dem Projekt hinzugefügt 
wird. In die Headerdatei kommen ausschließlich Deklarationen und evtl. 
benötigte Typdefinitionen, die auch von anderen Programmteilen 
verwendbar sein sollen.

Manch einer bezeichnet (fälschlicherweise) die Kombination aus einer 
.h-Datei und der dazugehörigen .c-Datei als "Header". Header ist aber 
nur die .h-Datei.

Wenn Du irgendeine LCD-Lib benutzen willst, dann hast Du im Regelfall 
eine .c-Datei (z.B. lcd.c) und eine .h-Datei (z.B. lcd.h). Die .h-Datei 
wird mittels #include ins Programm eingebunden, die .c-Datei gibst Du 
dem Compiler über das Makefile bzw. bei Benutzung einer IDE über die 
Projektkonfiguration bekannt. Die muss separat kompiliert werden.

Die Headerdatei dient ausschließlich dazu, dass der Compiler beim 
Kompilieren Deines Programms die zur Verfügung stehenden Funktionen, 
Variablen und Typen kennt.

von Sebastian D. (bineuling)


Lesenswert?

Danke für die schnelle Antort !

Jetzt tun sich jedoch weitere Fragen auf. Du hast geschriben:

"Die .h-Datei
wird mittels #include ins Programm eingebunden, die .c-Datei gibst Du
dem Compiler über das Makefile bzw. bei Benutzung einer IDE über die
Projektkonfiguration bekannt. Die muss separat kompiliert werden."

1. Stehen in header nur die funktionsnamen, und wenn ja, habe ich 
jeweils einen header für eine source datei ?

2. Beim Thema IDE und Makefile bin ich absoluter neuling. Kann ich die 
source files nicht einfach per #include-befehl ins Hauptprogramm main.c 
einbinden ?

mfg

von Johannes M. (johnny-m)


Lesenswert?

Sebastian Deubl wrote:
> 1. Stehen in header nur die funktionsnamen, und wenn ja, habe ich
> jeweils einen header für eine source datei ?
Wenn Du eine Quelldatei hast, die Funktionen und Variablen enthält, die 
auch von anderen Quelldateien verwendet werden sollen, dann kommt von 
jeder Funktion bzw. Variable eine Deklaration in die dazugehörige 
Headerdatei, die sinnvollerweise den selben Namen tragen sollte.

Bei Funktionen kommen da also Prototypen rein (also z.B. "void 
funktion(int);"). Bei Variablen muss eine Deklaration mit dem 
Schlüsselwort extern eingeleitet werden, da der Compiler hier nicht 
aus der Syntax ableiten kann, ob es sich um eine Definition oder eine 
Deklaration handelt (jede Variable oder Funktion darf in einem Projekt 
nur ein einziges Mal definiert, aber beliebig oft deklariert werden; 
eine Deklaration ist ja nichts anderes, als eine Mitteilung an den 
Compiler, dass irgendwo, evtl. in einer anderen Quelldatei, eine 
Variable bzw. Funktion definiert ist und er sie benutzen kann, während 
eine Definition für den betreffenden Bezeichner Speicherplatz 
reserviert).

Der ganze Krampf ist deshalb nötig, weil jede Quelldatei einzeln 
kompiliert wird (der Compiler weiß beim Kompilieren einer Quelldatei 
nicht, dass es noch andere Quelldateien gibt, die zum Projekt gehören). 
Der Compiler erzeugt aus jeder Quelldatei ein Objekt. Die einzelnen 
Objekte werden am Ende vom Linker zusammengebaut, und erst da werden die 
einzelnen Bezeichner abgeglichen.

Der Compiler muss nur bei der Verwendung eines Bezeichners wissen, dass 
irgendwo eine Variable / Funktion des angegebenen Typs existiert. Er tut 
dann so, als wäre die Variable da. Wenn der Linker dann am Ende merkt, 
dass ein Bezeichner zwar deklariert, aber nirgends definiert wurde, dann 
gibt's eine entsprechende Fehlermeldung.

> 2. Beim Thema IDE und Makefile bin ich absoluter neuling. Kann ich die
> source files nicht einfach per #include-befehl ins Hauptprogramm main.c
> einbinden ?
Nein! .c-Dateien werden nie mit #include eingebunden! Wenn Du mit 
AVRStudio arbeitest, dann musst Du alle Sourcen in den Projektbaum bei 
Source Files einfügen. Einfacher geht es wirklich nicht! Wenn Du mit 
einem Makefile arbeitest, dann müssen die Sourcen da in die 
entsprechende Zeile eingetragen werden.

von Sebastian D. (bineuling)


Lesenswert?

Vielen Dank für die detailierte Antwort. Um das ganze besser zu 
verstehen wäre es nett wenn du mir vielleicht ein einfaches 
beispielprojekt senden könntest an dem man die struktur erkennen kann. 
Das ganze Thema ist nämlich komplizierter als ich dachte. Mir fehlen 
halt auch die Begriffsdefinitionen von Deklaration, Definition, Prototyp 
und dergleichen.

Danke !

von Johannes M. (johnny-m)


Lesenswert?

Sebastian Deubl wrote:
> Vielen Dank für die detailierte Antwort. Um das ganze besser zu
> verstehen wäre es nett wenn du mir vielleicht ein einfaches
> beispielprojekt senden könntest an dem man die struktur erkennen kann.
> Das ganze Thema ist nämlich komplizierter als ich dachte.
So kompliziert ist das gar nicht. Aber für die Grundlagen ist hier im 
Forum kein Platz.

> Mir fehlen
> halt auch die Begriffsdefinitionen von Deklaration, Definition, Prototyp
> und dergleichen.
Da wirst Du Dir wohl ein gutes Buch zum Thema C nehmen müssen...

von Sebastian D. (bineuling)


Lesenswert?

Trotzdem Danke !

von Helmut -. (dc3yc)


Lesenswert?

Schau doch mal hier im Wiki unter "Include-Files (C)". Dort steht 
vielleicht für dich Interessantes drin!

Servus,
Helmut.

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
Noch kein Account? Hier anmelden.