Forum: Compiler & IDEs Verständnisfrage Header/include WinAVR


von Gast123 (Gast)


Lesenswert?

Hallo,

ich hab eine Frage zur Verwendung von #include bzw. Header-Dateien. 
Etwas googlen und suchen in den Forumsbeiträgen brachte mich zur 
folgenden (etwas vereinfachten) allgemeinen Form:
1
/* header.h */
2
void function_1(void);  // Prototyp von function_1
3
void function_2(void);  // Prototyp von function_2
4
// usw.
5
6
7
/* header.c */
8
#include "header.h"  
9
10
void function_1(void)
11
  {
12
  // mach irgendwas..
13
  }
14
15
void function_2(void)
16
  {
17
  // mach irgendwas anderes..
18
  }
19
20
21
/* main.c */
22
#include <...>       // Standard-Bibliotheken einbinden
23
#include "header.h"  // <-- hier setzt meine Frage an (siehe unten)
24
25
void main(void)
26
  {
27
  // Hauptprogramm..
28
  }

Meine Frage ist nun, warum wird im Hauptprogramm die *.h-Datei 
eingebunden und nicht die *.c-Datei?

Ok, aus der *.h kennt der Compiler erstmal die Prototypen. Ok, soweit so 
gut. Aber woher kennt er dann die genaue Implementierung der Funktionen 
(heisste das so?)? Wird einfach davon ausgegangen, dann *.h und *.c den 
selben Namen haben?

Logischer für mich würde es irgendwie klingen, wenn ich im Hauptprogramm 
die *.C einbinde. Die Datei wiederum bindet dann die *.h ein und die 
Welt ist in Ordnung :-)

Sehe ich das richtig, dass ich auch einfach einige Funktionen in eine 
*.c auslagern kann und dann mit include "xyz.c" einbinden kann, ohne 
Header zu benutzen? (für nicht garzu allgemein nutzbare Funktionen vor 
allem).

Gruß und schonmal Danke für Erleuchtung :-)
Christian

von Peter (Gast)


Lesenswert?

Zuallererst werden die include-Files im C-File eingefügt und auch alle 
weiteren Preprocessor-Anweisungen durchgeführt, (alle Zeilen die mit "#" 
beginnen) wie z.B. Macros substituieren.

Der Compiler übersetzt dann vorest jedes C-File einzeln zu einem 
Object-File => *.o File. Anhand der Prototypen-Deklarationen nimmt er 
an, dass die Funktion irgendwo in einem anderen Objectfile existiern 
wird,fall sie nicht schon im selben C-File vorkommt und setzt die 
entsprechenden Labels für den Linker.

Erst der Linker fügt dann alle Object-Files zu einem Programm zusammen.

Durch das Makfile weiss der Compiler+Linker welche Dateien zusammen 
gehören bzw aus welchen Source-Dateien das Programmm zusammengebaut 
werden soll.

von gast (Gast)


Lesenswert?

Es können *.c UND *.h Dateien eigebunden werden. Ob man *.c Dateien 
einbindet ist eigendlich nur eine Frage vom Programmierstil. Ob. die 
Funktionsdeklaration in einer *.h Datei steht hängt davon ab, ob man mit 
mehreren Dateien arbeitet und diese auf die Deklarierten Funkionen 
zugreifen müssen. In deinem Beispiel ist eine *.h Datei nicht notwendig. 
Ich persönlich halte es so, dass es in meinen Projekten nur eine Datei 
MAIN.c OHNE MAIN.h gibt. In MAIN erfolgt dann nur die Initialisierung 
und der Aufruf des Schedulers.

von Oliver (Gast)


Lesenswert?

>Es können *.c UND *.h Dateien eigebunden werden.

Können kann man alles einbinden, aber wenn überhaupt, gibt es nur ganz 
wenige Spezialfälle, wo das einbinden von .c-Dateien sinnvoll ist. 
Normalerweise braucht man das nicht.

Das funktioniert so, wie Peter es schon beschrieben hat.

Oliver

von Gast123 (Gast)


Lesenswert?

Woher weiss der Compiler aber, dass die Datei Header.c mit übersetzt 
werden muss? Die wird ja nirgends mittels #include oder so erwähnt.

(Meine Funktionen hab ich nun erstmal alle mittels #include "zeugs.c" in 
eine andere Datei verlagert. So ists erstmal nicht garzu unübersichtlich 
in der Hauptdatei. Um die Funktionen ordentlich in nem anderen Projekt 
wiederverwenden zu können, müsste ich aber wohl einiges noch ein 
bisschen allgemeiner Formulieren und einige Überprüfungen einbauen.)

Bitte mich weiter erleuchten :-) :-)

Gruß und Danke
Christian

von Simon K. (simon) Benutzerseite


Lesenswert?

Gast123 wrote:
> Woher weiss der Compiler aber, dass die Datei Header.c mit übersetzt
> werden muss? Die wird ja nirgends mittels #include oder so erwähnt.
Durch das MAKEFILE. Oder auch dadurch, dass du alle C-Dateien der IDE 
hinzufügst, mit der du programmierst.

> (Meine Funktionen hab ich nun erstmal alle mittels #include "zeugs.c" in
Sowas macht man nicht, auch wenn es (erstmal) funktioniert ;)

von Gast (Gast)


Lesenswert?

Der Compiler weiss es nicht. Er muss für jede Datei einzeln aufgerufen 
werden. Erst der Linker erstellt daraus (wie bereits oben geschrieben) 
"eine" fertige Programmdatei.

Damit man nicht jede Datei einzeln kompilieren und anschließend den 
Linker (vereinfacht ausgedrückt: den Zusammensetzer) aufrufen muss, gibt 
es die sogenannten Make-Dateien. Das ist soetwas wie eine Skriptdatei 
die vorher definierte Abläufe durchführt. In dieser Make-Datei muss jede 
*.c Datei eingetragen werden so dass sie vom Compiler nach und nach 
übersetzt wird. Jede c-Datei für wird für sich und ohne Wissen der 
anderen Objektdateien übersetzt. Damit nun Aufrufe aus anderen *.c 
Dateien nicht zu fehlern führen geht der Compiler davon aus, dass alle 
Funktionen die in Headerdateien definiert sind, beim linken mit in das 
endgültige Programmpaket eingefügt werden.

Steffen.

von Gast123 (Gast)


Lesenswert?

1
...
2
# Output format. (can be srec, ihex, binary)
3
FORMAT = ihex
4
5
6
# Target file name (without extension).
7
TARGET = main
8
9
10
# List C source files here. (C dependencies are automatically generated.)
11
SRC = $(TARGET).c     # <--- HIER?
12
13
14
# List Assembler source files here.
15
#     Make them always end in a capital .S.  Files ending in a lowercase .s
16
#     will not be considered source files but generated files (assembler
17
#     output from the compiler), and will be deleted upon "make clean"!
18
#     Even though the DOS/Win* filesystem matches both .s and .S the same,
19
#     it will preserve the spelling of the filenames, and gcc itself does
20
#     care about how the name is spelled on its command-line.
21
ASRC = 
22
...

Aaaaah, langsam beginne ich zu verstehen :-) :-) Also könnte ich in dem 
obigen Schnipsel aus dem makefile meine Datei zeugs.c eintragen (und 
nicht per #include im Hauptprogramm). Die Datei würde dann separat 
übersetzt werden. Dann würde aber wohl der Compiler beim hauptprogramm 
meckern, weil er die Funktionen nicht kennt. Das wiederum würde man 
durch die zeugs.h umgehen, die die Funktionsprototypen enthält.

Nur #include "zeugs.h" im Hauptprogramm, ohne die zeugs.c im Makefile zu 
erwähnen würde also nicht funktionieren.

Ist das soweit richtig.. ? :-)

Vielen Dank und nen schönen Abend noch :-)
Christian

von Simon K. (simon) Benutzerseite


Lesenswert?

Gast123 wrote:
> Nur #include "zeugs.h" im Hauptprogramm, ohne die zeugs.c im Makefile zu
> erwähnen würde also nicht funktionieren.
>
> Ist das soweit richtig.. ? :-)

Jep genau. Das Kompilieren würde zwar funktionieren, aber beim Linken 
meldet der Linker dann, dass er bestimmte Objekte (also die Funktionen), 
die der Compiler in das Objectfile eingtragen hat, nicht finden kann.

von Gast123 (Gast)


Lesenswert?

Demzufolge muss man das makefile also immer anpassen. Bisher dachte ich, 
das wäre nur bei Änderung am Prozessortyp oder der Taktfrequenz 
notwendig.

Juhu, ich glaub ich habs verstanden :-)

Vielen Dank an alle fleißigen Erklärer :-)

Gruß und noch ein schönes Wochenende
Christian

von Klaus (Gast)


Lesenswert?

wenn du eine IDE wie z. B. WinAVR benutzt wird dir das erstellen des 
makefiles in der Regel abgenommen und du musst dich um nix kümmern.

von Steffen (Gast)


Lesenswert?

Ist WinAVR ne IDE? Egal, wenn du mit dem AVRStudio arbeitest wird das 
für dich übernommen. Einfach die C Datei ins Projekt einfügen.

STeffen.

von Gast123 (Gast)


Lesenswert?

Momentan verwende ich WinAVR. Das AVR-Studio hatte ich vor einer Weile 
für ASM benutzt, aber seit einem Weilchen soll das ja auch C verstehen. 
Werd ich demnächst ausprobieren. Wobei die Modifikation am Makefile nun 
auch nicht die große Sache ist - wenn man erstmal kapiert hat dass und 
warum es erforderlich ist :-)

Gruß
Christian

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.