mikrocontroller.net

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


Autor: Gast123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:

/* header.h */
void function_1(void);  // Prototyp von function_1
void function_2(void);  // Prototyp von function_2
// usw.


/* header.c */
#include "header.h"  

void function_1(void)
  {
  // mach irgendwas..
  }

void function_2(void)
  {
  // mach irgendwas anderes..
  }


/* main.c */
#include <...>       // Standard-Bibliotheken einbinden
#include "header.h"  // <-- hier setzt meine Frage an (siehe unten)

void main(void)
  {
  // Hauptprogramm..
  }


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

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Gast123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Gast123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...
# Output format. (can be srec, ihex, binary)
FORMAT = ihex


# Target file name (without extension).
TARGET = main


# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c     # <--- HIER?


# List Assembler source files here.
#     Make them always end in a capital .S.  Files ending in a lowercase .s
#     will not be considered source files but generated files (assembler
#     output from the compiler), and will be deleted upon "make clean"!
#     Even though the DOS/Win* filesystem matches both .s and .S the same,
#     it will preserve the spelling of the filenames, and gcc itself does
#     care about how the name is spelled on its command-line.
ASRC = 
...

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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Gast123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Gast123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.