Forum: Mikrocontroller und Digitale Elektronik define, extern, Controller Libs


von Reine (Gast)


Lesenswert?

Hallo,

Ich weiß dass es zu der Diskussion ob man extern oder ein include 
benutzen sollte, viele Themen gibt.

Was ich mich jedoch frage: was ist mit großen, Controller spezifischen 
Header Dateien, oder zum Beispiel mit der stdint.h Header Datei? Im 
Moment includiere ich zum Beispiel die stdint.h in mehreren Dateien, da 
ich die dort benötige. Diese Dateien werden auch in der main.c 
includiert. Also steht der Inhalt dieser Datei mehrfach in meiner 
main.c, da ich auch in der main.c die stdint.h zur Benutzung include ?!

Ausserdem: wenn ich mit extern einen Funktions prototypen aus einer 
anderen Datei benutzen will, muss das "extern void func1prototype();" in 
die Header Datei oder in die C Datei, in der ich diese benutzen möchte ? 
Ich hätte jetzt in die c Datei getippt, denn würde ich diese in die .h 
Datei setzen, hätte ich schon wieder ein mehrfach Include falls diese 
Header Datei wieder wo anders includiert wird wo "void 
func1prototype();" benutzt wird.

Es geht um C.


lG
Reine

von Harry L. (mysth)


Lesenswert?

1. ist Extern keine Alternative zu Include (das ist etwas vollkommen 
Anderes), und 2. wird eine (korrekte) Include-Datei tatsächlich immer 
nur einmal eingefügt/ausgewertet, egal, wie oft du die mit #include 
referenzierst.

Schau dir die Include-Datei mal an, dann verstehst du vermutlich warum 
das so ist.

C-Grundlagen lernen!!!

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Reine schrieb:
> Also steht der Inhalt dieser Datei mehrfach in meiner
> main.c, da ich auch in der main.c die stdint.h zur Benutzung include ?!

Nein, da die sogenannten Include-Guards in 99,9% der Header das 
verhindern:
1
#ifndef MY_HEADER_H
2
#define MY_HEADER_H
3
4
enum my_enum { a, b, c };
5
void funktion1 (int a);
6
char funktion2 (char b);
7
8
#endif
Achtung: Bezeichner die mit Unterstrich + Großbuchstabe anfangen sind in 
C(++) der Standard-Bibliothek vorenthalten. So etwas sieht man oft, ist 
daher aber falsch:
1
#ifndef _MY_HEADER_H
2
#define _MY_HEADER_H
3
4
enum my_enum { a, b, c };
5
void funktion1 (int a);
6
char funktion2 (char b);
7
8
#endif

Reine schrieb:
> sserdem: wenn ich mit extern einen Funktions prototypen aus einer
> anderen Datei benutzen will, muss das "extern void func1prototype();" in
> die Header Datei oder in die C Datei, in der ich diese benutzen möchte ?

Das "extern" an Funktionen hat keine Wirkung und ist überflüssig. 
Prinzipiell geht beides, aber es ist dringend dazu zu raten, den 
Prototypen in die Header-Datei zu schreiben. Wenn der Prototyp in jeder 
Datei, die ihn nutzt, wiederholt wird, hat man eine Dopplung welche die 
Wartung erschwert und Fehler provoziert - wenn man beim Abschreiben 
etwas falsch macht, oder bei Änderung der Funktions-Signatur vergisst 
eine Datei anzupassen, passt der Prototyp nicht mehr zur Definition und 
man bekommt lustige Laufzeit-Fehler.

Außerdem sollte man auf jeden Fall in der C-Datei mit der 
Funktions-Definition den Header ebenfalls inkludieren, denn so findet 
der Compiler Unstimmigkeiten zwischen Prototyp und Funktion.

Reine schrieb:
> hätte ich schon wieder ein mehrfach Include falls diese
> Header Datei wieder wo anders includiert wird wo "void
> func1prototype();" benutzt wird.
Das passiert wie gesagt nicht.

von Reine (Gast)


Lesenswert?

Stimmt, ein Include Guard in meinen eigenen Header Dateien einzubauen 
ist eine sehr saubere Lösung! Werde ich sofort umsetzen.

Was mich allerdings in verschiedenen Fällen dran hindert:
Folgendes:

mix.h :
void func1();
void func2();
void important1();
void important2();

In der mix.c werden diese Funktionen verarbeitet.

In einer anderen Datei (oeffentlich.c) möchte ich jetzt NUR die void 
func1() und void func2() aus der mix.h benutzen. Dann macht es hier 
keinen Sinn per Include die mix.h zu benutzen, sondern eher in der 
oeffentlich.c einfach einen extern void func1() und extern void func2() 
die Prototypen bekannt geben? Somit sieht die oeffentlich.c die 
(internen) Prototypen important1 und important2 nicht.

Kann das jemand so unterschreiben?

Vielen Dank!

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Reine schrieb:
> Dann macht es hier
> keinen Sinn per Include die mix.h zu benutzen, sondern eher in der
> oeffentlich.c einfach einen extern void func1() und extern void func2()
> die Prototypen bekannt geben?
Auf keinen Fall. Die unnötig eingelesenen Funktions-Prototypen schaden 
nicht. Wenn important1/2 intern sind, definiere sie nicht im Header 
sondern halt nur in der mix.c . Wenn du von mehreren C-Dateien auf 
interne Funktionen zugreifen musst (warum?), kannst du auch zwei Header 
anlegen - mix.h und mix_private.h, und letzteren nur von den C-Dateien 
aus inkludieren, die auf die internen Funktionen zugreifen müssen.

Eigentlich muss man niemals Prototypen in .c-Dateien schreiben, außer 
wenn die Funktion weiter unten in der selben Datei definiert ist, sie 
aber nicht öffentlich sein soll.

von Dirk B. (dirkb2)


Lesenswert?

Niklas G. schrieb:
> kannst du auch zwei Header
> anlegen - mix.h und mix_private.h,

mix-private.h wäre aber nur nötig, wenn der Code von mix über mehrere .c 
Dateien verteilt ist.
Wenn es nur mix.c gibt kann man den Inhalt von mix_private.h auch gleich 
in mix.c schreiben.

Die Headerdateien dienen als Schnittstellenbeschreibung (für andere 
Quelldateien). Was nicht nach außen soll, kommt erst gar nicht rein.

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.