Hallo bin beu einem Projekt mit den Datein in .C und .H etwas durcheinander gekommen. Was muss in die (Datei).C und was muss in die (Datei).H? Es geht dabei um selbstgeschriebene Datein mit den verschiedenen Teilen eines Programmes. Dabei besonders um die ganzen voids. Teilweise nehmen diese Teile eines Programmes viel Platz ein oder um wiederkehrende Teile eines Programmes mehrfach zu nutzen. achim
Achim S. schrieb: > Dabei besonders um die ganzen voids was meinst du damit? > Was muss in die (Datei).C und was muss in die (Datei).H? in C sollte die Implementierung der Funktionen in H sollte die Definition der Funktionen
Hallo Was sollen voids sein? Variablen? Funktionen? Sorry wenn ich falsch liege, aber ich glaube Du solltest Dich nochmal mit den Grundlagen zu C beschäftigen. Zumindest vermittelt mir Dein Post den Eindruck. Zu deiner Frage was in die Headerfile soll empfehle ich dir diesen Artikel: http://embeddedgurus.com/barr-code/2010/11/what-belongs-in-a-c-h-header-file/ (Die Kommentare unter dem Blogpost sind auch interessant...) Generell kann man auf der Seite viele Ideen und Anregungen zur Verbesserung des eigenen Programmierstils finden ;) Viel Erfolg!
Mit void meine ich das: void Versuch() { mach was: } Ich finde es wieder sehr hilfreich von euch, wenn ihr einfach auf ein Fachbuch verwaist. Wenn ich die ganzen Beiträge hier oder im Netz so ansehe, scheint es sehr kompliziert zu sein, was was ist. Oder habe ich eine einfache, nicht komplizierte Erklärung überlesen? Das sieht schon so aus, was ich suche: Peter II schrieb: >> Was muss in die (Datei).C und was muss in die (Datei).H? > in C sollte die Implementierung der Funktionen > in H sollte die Definition der Funktionen In (Datei).c Implementierung der Funktion und in (Datei).h die eigentliche Definition der Funktion achim
Achim S. schrieb: > Mit void meine ich das: > > void Versuch() > { > mach was: > } Ah, das ist also ein "void". Eine Funktionsdefinition, die in diesem Fall eben den Rückgabetyp void hat... > Das sieht schon so aus, was ich suche: > > Peter II schrieb: >>> Was muss in die (Datei).C und was muss in die (Datei).H? >> in C sollte die Implementierung der Funktionen >> in H sollte die Definition der Funktionen > > In (Datei).c Implementierung der Funktion > und in (Datei).h die eigentliche Definition der Funktion Die Implementierung ist die eigentliche Definition der Funktion. In den Header gehört die Deklaration. Diese macht nur Name und Typ der Funktion bekannt. Ins C-File gehört dann die Implementation, also der eigentliche Inhalt der Funktion.
>Mit void meine ich das: >void Versuch() Ja, das void hatte mich früher auch immer irritiert. Übersetzt heißt es "leer" und im Bezug auf die Funktion bedeutet es, dass die Funktionen nichts zurück gibt.
Achim S. schrieb: > Mit void meine ich das: > > void Versuch() > { > mach was: > } ...ja und? Frage an dich: was sind/machen den dir "void"s? Wenn du mal eins der angesprochenen C-Bücher gelesen hättest, würdest du nicht eine solche Frage stellen! Qualifizierte und beantwortbare Fragen kann man nur dann sinnvoll stellen, wenn man die entsprechenden Grundlagen kennt. Deine Frage liest sich etwas verwirrt, was die Beantwortung nicht leichter macht!
in *.c muss rein, was selbständig kompilierbar sein soll. In *.h muss rein, was die main-Datei braucht, um die selbständig kompilierten c-Dateien zu erfassen.
grundschüler schrieb: > in *.c muss rein, was selbständig kompilierbar sein soll. In *.h muss > rein, was die main-Datei braucht, um die selbständig kompilierten > c-Dateien zu erfassen. ...nicht ganz: xxx.h sollte auch das enthalten, was zum (eigenständigen) Übersetzen von xxx.c benötigt wird.
und was muss in die (Datei).H? In .c kommt der Code, also das was durch den Compiler zu ausführbarem Code wird, dein // mach was. .c
1 | void Versuch() |
2 | { |
3 | // mach was |
4 | } |
In .h kommt nur die Definition, also der Funktionsname ohne Body. .h
1 | void Versuch(void); |
und damit der Compiler prüfen kann, ob beides übereinstimmt, nimmt man den .h in den .c durch ein #include auf .c
1 | #include "versuch.h" |
2 | void Versuch() |
3 | { |
4 | } |
In den Programmteilen, die dann die Library versuch.lib verwenden, nimmt man auch die .h Datei per #include auf. Dann kann man due Funktion Versuch von dort aufrufen, obwohl es den Code nur in der Library gibt. Auch ohne Library macht man das so, wenn man das Programm in 2 .c Dateien aufteilt. main.c enthält #include "versuch.h" und darf damit die Funktion Versuch() aufrufen die in versuch.c steht, wenn man beides zusammen kompiliert gcc main.c versuch.c -o programm.exe
MaWin schrieb: > In .h kommt nur die Definition Das heißt immer noch Deklaration. Und noch ein Tipp: Die .h sollte man immer so aufbauen:
1 | #ifndef my_h
|
2 | #define my_h
|
3 | // alle relavanten deklarationen
|
4 | #endif
|
Das hat den Vorteil, wird die my.h in verschiedenen Programmbereichen includiert, so wird sie vom Compiler nur ein einziges mal eingefügt und nicht mehrfach was ja das Target unnötig sonst vergrößern würde.
Achim S. schrieb: > Was muss in die (Datei).C und was muss in die (Datei).H? Ganz einfach. Alles, was Code oder Daten erzeugt, kommt ins c-File, alles andere ins h-File. Im h-File stehen also alle Deklarationen, Macros, Inline-Funktionen. Kommentare (Funktionsbeschreibungen) sollten in beiden stehen. Zu jedem c-File gehört ein gleichnamiges h-File, wo alles drinsteht, was andere Funktionen zur Nutzung des c-Files brauchen.
>Ganz einfach. Alles, was Code oder Daten erzeugt, kommt ins c-File, >alles andere ins h-File. Sehr interessant ist aber auch die Frage: 1. wann kommen includes in include files 2. wann kommen includes ins c-files
1 & 2: Wenn sie dort gebraucht werden. Im übrigen hat nichts von den hier betrachteten Fragestellungen irgendwas mit Libraries zu tun. Weder *.c noch *.h-Dateien sind Libraries.
chris_ schrieb: > 1. wann kommen includes in include files > 2. wann kommen includes ins c-files Auch ganz einfach: Immer dann, wenn es Fehler oder Warnungen gäbe, sobald im Code kein anderes Include davor steht. Z.B. eine Deklaration benutzt uint8_t, dann muß das <stdint.h> includiert werden. Sauber ist es, ins c-File die gleichen Includes zu schreiben und das gleichnamige *.h und die *.h aller benötigten Funktionen.
>Auch ganz einfach:
Hmm ... ich hätte da noch folgenden Vorschlag:
1. mit includes kann man die Interfacefunctionen von Libraries sichtbar
machen
2. will man eine Libray includieren dann sind alle Deklarationen der
include-Files in den Include Files für den "Includierer" sichtbar
3. Das ist nicht immer erwünscht, in diesem Fall fügt man die includes
ins C-File
> mit den Datein in .C und .H etwas durcheinander > gekommen. > um die ganzen voids. > nehmen ... viel Platz ein q.e.d.1: Programmieren ist komplex und erfordert abstrahierendes Denkvermögen UND Disziplin. (beides kann nicht Jeder gleich gut) q.e.d.2: die Familie der C-Sprachen IST KOMPLIZIERT. Jedenfalls komplizierter als nötig um "Programmierung" in der Realität umzusetzen. Die C-Familie trennt nicht sauber Low-Level von High-Level noch ist Modularisierung sauber umgesetzt: alles ist ein zu pragmatisches, organisch gewuchertes Mischmasch. Alles wird auf die Disziplin des Programmieres abgewälzt; von Ihm werden allzutiefe UND breite Vorkenntnisse vorausgesetzt inkl. das ständige vorhalten des gesamten Wissens darüber.
MaWin schrieb: > In .h kommt nur die Definition, also der Funktionsname ohne Body. DEKLARATION! Ist das denn so schwierig?
Peters Beitrag beschreibt die gängige Praxis am besten, so sollte man es machen. Nur noch ein paar kleine Anmerkungen: Peter D. schrieb: > Ganz einfach. Alles, was Code oder Daten erzeugt, kommt ins c-File, Exakt. Von dieser Regel gibt es auch kaum Ausnahmen, so dass sich ein Programmieranfänger immer daran halten sollte. Das "was Code oder Daten erzeugt" ist im C-Standard genau festgelegt und nennt sich dort "external definition". > alles andere ins h-File. Nicht unbedingt. Deklarationen, die nur in einer einzigen Überstzungseinheit genutzt werden, dürfen gerne auch in deren .c-Datei stehen. Wenn solche lokalen Deklarationen aus Übersichtsgründen in eine .h-Datei ausgelagert werden, sollten sie nicht mit Deklarationen vermischt werden, die in mehreren Übersetzungseinheiten genutzt werden. > Im h-File stehen also alle Deklarationen, Macros, Inline-Funktionen. Ersetze "alle" durch "ausschließlich", dann stimmt's. > Zu jedem c-File gehört ein gleichnamiges h-File, wo alles drinsteht, was > andere Funktionen zur Nutzung des c-Files brauchen. Wenn es nichts gibt, was von anderen Übersetzungseinheiten benutzt wird, kann man sich die .h-Datei schenken. Das betrifft aber normalerweise nur diejenige .c-Datei, die die main()-Funktion enthält. Wenn mehrere Übersetzungseinheiten zu einer Bibliothek zusammengefasst werden, kann man (muss aber nicht) auch die .h-Dateien zusammenzufassen, um deren Anzahl etwas zu verringern.
Es gibt verschiedene Arten wie man eine .h Datei verwenden kann. Dieses einfache Deklarationen in die .h und Implementationen in die .c finde ich nicht immer günstig. In Programmen mit vielen .c und .h Dateien kann es da schnell zu Doppelbenamungen kommen. Für mich kommen nur die Deklarationen in die .h rein, die auch außerhalb der .c Datei bekannt sein sollen. zB.: ich habe die Funktionen dateiauslesen() und kleine_hilfsfunktion() in einer dateifunktionen.c da würde bei mir die die Deklaration der dateiauslesen() in die dateifunktionen.h kommen und die Deklaration der kleine_hilfsfunktion(), sowie die Implementationen der beiden Funktionen in die dateifunktionen.c Datei. Eine Weitere sinvolle Verwendung von .h Dateien ist die übersichtliche Sammlung von #define Einträgen. zB. für ein Programm das eine Temperatur überwachen soll. Die verschiedenen Temperatur-Grenzwerte könnten dann gesammelt in einer Temperatur.h stehen. In dieser Datei steht dann aber nichts anderes mehr drin (außer Kommentare natürlich). Somit ist ein größeres Programm sehr übersichtlich und Parameter können schnell gefunden und angepasst werden
Yalu X. schrieb: >> Im h-File stehen also alle Deklarationen, Macros, Inline-Funktionen. > > Ersetze "alle" durch "ausschließlich", dann stimmt's. Nein, denn da müssen z.B. auch Typdefinitionen stehen.
chris_ schrieb: > Ja, das void hatte mich früher auch immer irritiert. Übersetzt heißt es > "leer" und im Bezug auf die Funktion bedeutet es, dass die Funktionen > nichts zurück gibt. Was dazu im Wörterbuch als Bedeutung steht, ist ziemlich belanglos. In C handelt sich um einen Datentyp. Eine Variable des Datentyps void hat die Länge 0 mit einer Leeren Menge als Wertebereich.
my2ct schrieb: > Eine Variable des Datentyps void hat die Länge 0 mit einer Leeren Menge > als Wertebereich. Mit welchem Compiler kann man denn eine Variable vom Typ void deklarieren?
error: variable has incomplete type 'void' schrieb: > my2ct schrieb: >> Eine Variable des Datentyps void hat die Länge 0 mit einer Leeren Menge >> als Wertebereich. > > Mit welchem Compiler kann man denn eine Variable vom Typ void > deklarieren? Variablen vom Typ void kann man nicht anlegen, da void per Defintion ein unvollständiger Typ ist. Eine Größe hat void damit in dem Sinne einfach nicht, genausowenig wie einen Wertebereich.
Achim S. schrieb: > Mit void meine ich das: > > void Versuch() > { > mach was: > } Oh, dann ist das so etwas wie ein 710er-Deckel! Kannst Du uns im Gegenzug vielleicht erklären, wozu solch ein Deckel gut ist? http://www.rainereisenhuth.de/710erdeckel.jpg
void hat nur seinen Platz in Funktionsdeklarationen als Argument bzw. Returntyp. Dirty (void*) casts sollte man möglichst vermeiden. Deklaration: Funktion/Variable bekannt machen Definition: Funktion/Variable mit Inhalt füllen Formalismen helfen vorrangig Dir, dem Programmierer, auch wenn das ein Anfänger ungern einsehen will. Daß Du dann weniger Fehler machst bzw. Fehler schneller findest, ist pure Absicht. Daß ein anderer Deinen Code besser lesen kann oder weniger meckert, ist nur ein kleiner Nebeneffekt.
Rolf M. schrieb: > Yalu X. schrieb: >>> Im h-File stehen also alle Deklarationen, Macros, Inline-Funktionen. >> >> Ersetze "alle" durch "ausschließlich", dann stimmt's. > > Nein, denn da müssen z.B. auch Typdefinitionen stehen. Ich wollte das in meinem obigen Beitrag erst ebenfalls anmerken, habe es dann aber gelassen, da auch Typdefinitionen Deklarationen sind. Dass das so ist erkennt man daran, dass sie im C-Standard auch im Abschnitt "Deklarations" abgehandelt werden.
c-basics schrieb: > grundschüler schrieb: >> in *.c muss rein, was selbständig kompilierbar sein soll. In *.h muss >> rein, was die main-Datei braucht, um die selbständig kompilierten >> c-Dateien zu erfassen. > > ...nicht ganz: xxx.h sollte auch das enthalten, was zum (eigenständigen) > Übersetzen von xxx.c benötigt wird. Nein. In xxx.h kommen nur die Schnittstelleninformationen rein. Interne Funktionen und Informationen bleiben in xxx.c
Andreas S. schrieb: > Oh, dann ist das so etwas wie ein 710er-Deckel! Hier kann man den auch kaufen ;-) http://etel-tuning.eu/exterieur/171-der-710-er.html Yalu X. schrieb: > Ich wollte das in meinem obigen Beitrag erst ebenfalls anmerken, habe es > dann aber gelassen, da auch Typdefinitionen Deklarationen sind. Dass das > so ist erkennt man daran, dass sie im C-Standard auch im Abschnitt > "Deklarations" abgehandelt werden. Nach der Logik würden dann aber auch die Funktions-Definitionen dorthin gehören, denn die sind ja auch gleichzeitig Deklarationen. Eine Definition ist aber nicht "ausschließlich" eine Deklaration. Um's nochmal zusammenzufassen: Funktionen werden in Headern nur deklariert. Globale Variablen ebenfalls. Typen müssen dagegen - sofern sie von verschiedenen c-Files aus nutzbar sein sollen, im Header definiert werden, nicht nur deklariert.
:
Bearbeitet durch User
Rolf M. schrieb: > Typen müssen dagegen - sofern sie von verschiedenen c-Files aus nutzbar > sein sollen, im Header definiert werden, nicht nur deklariert Ausser man nutzt nur einen Pointer auf den Datentyp, und dereferenziert diesen nicht. So kann man auch unvolständige typen nutzen.
Rolf M. schrieb: > Yalu X. schrieb: >> Ich wollte das in meinem obigen Beitrag erst ebenfalls anmerken, habe es >> dann aber gelassen, da auch Typdefinitionen Deklarationen sind. Dass das >> so ist erkennt man daran, dass sie im C-Standard auch im Abschnitt >> "Deklarations" abgehandelt werden. > > Nach der Logik würden dann aber auch die Funktions-Definitionen dorthin > gehören, denn die sind ja auch gleichzeitig Deklarationen. > Eine Definition ist aber nicht "ausschließlich" eine Deklaration. Es ist müßig, über die Begriffe und deren Auslegung diskutieren, denn die Regel kann letztendlich ganz einfach formuliert werden: ------------------------------------------------------------------------ Alles, was im C-Standard im Abschnitt "External definitions"¹ aufgeführt ist, gehört in eine .c-Datei. ------------------------------------------------------------------------ Diese Regel sagt implizit auch aus, dass alles andere wahlweise in einer .c- oder .h-Datei stehen darf. In welche .c- oder .h-Datei man nun die Dinge, die keine external Definitions sind, genau schreibt, das ist wieder ein anderes Thema und leider nicht durch eine ähnlich einfache Regel zu erschlagen. ———————————— ¹) Das sind Funktionsdefinitionen, die nicht inline sind, und externe Objektdefinitionen.
:
Bearbeitet durch Moderator
Daniel A. schrieb: > Rolf M. schrieb: >> Typen müssen dagegen - sofern sie von verschiedenen c-Files aus nutzbar >> sein sollen, im Header definiert werden, nicht nur deklariert > > Ausser man nutzt nur einen Pointer auf den Datentyp, und dereferenziert > diesen nicht. So kann man auch unvolständige typen nutzen. Gut, das hängt von der Definition von "nutzen" ab. Für mich ist es noch nicht Nutzung eines Datentyps, wenn ich einen Zeiger darauf von irgendwo bekomme und irgendwo anders wieder abgebe. Yalu X. schrieb: > Es ist müßig, über die Begriffe und deren Auslegung diskutieren, denn > die Regel kann letztendlich ganz einfach formuliert werden: > > ----------------------------------------------------------------------- > Alles, was im C-Standard im Abschnitt "External definitions" aufgeführt > ist, gehört in eine .c-Datei. > ----------------------------------------------------------------------- Ob es nun einfacher ist, aus dem C-Standard zu entnehmen, was "external definitions" sind oder eher ein paar mehr Regeln zu haben, sei mal dahingestellt. > Diese Regel sagt implizit auch aus, dass alles andere wahlweise in einer > .c- oder .h-Datei stehen darf. In welche .c- oder .h-Datei man nun die > Dinge, die keine external Definitions sind, genau schreibt, das ist > wieder ein anderes Thema und leider nicht durch eine ähnlich einfache > Regel zu erschlagen. Eine einfache Regel wäre, in das Interface, also den Header so wenig wie möglich, aber so viel wie nötig reinzustecken. Was man von außen nicht braucht, muss auch nicht im Header stehen.
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.