hi leute!
Ich habe mehrere .c datein, welche auf eine .h datei zugreifen sollen
(#include)
Ich bekomme aber leider jedes mal einen "Build Failed".
Ich will aber nicht die variablen 2 mal deklarieren (einmal normal, und
dann nochmal als extern!)
Hier ein bsp!
main.c:
1
#include"main.h"
2
3
main(void)
4
{
5
test(a);
6
tesst(b);
7
}
teil.c:
1
#include"main.h"
2
3
test(charaaa)
4
{
5
a++;
6
b=aaa;
7
}
anderer.c:
1
#include"main.h"
2
tesst(charbbbb)
3
{
4
b++;
5
a=bbbb;
6
}
main.h
1
#ifndef _main_h
2
#define _main_h
3
chara,b;
4
#endif
Ich weiss, dass ich bei teil.c & anderer.c die main.h datei entfernen
muesste, und dafuer ein extern char a,b schreiben muesste. Aber diese
abtipselei will ich mir sparen.
Gibt es hier irgendeinen trick?
bei globalen variablen wirst du da wohl nicht drumrum kommen...
gut man kann etwas machen wie:
main.h:
#ifndef _main_h
#define _main_h
#ifdef ISMAIN
#define blubb
#else
#define blubb extern
#endif
blubb char a,b;
#endif
------
main.c
#define ISMAIN
#include "main.h"
dann wird eben nur die variable im main source deklariert ansonsten als
extern...
ob das jetzt toll ist... ist ne andere frage ;)
Also "normal" wäre das so:
deklaration der variablen in main.h:
extern int blupp;
definition der varibalen in main.c:
int blupp;
anderes_file.c:
#include main.h
blupp = 172635;
> Ich weiss, dass ich bei teil.c & anderer.c die main.h datei entfernen> muesste, und dafuer ein extern char a,b schreiben muesste. Aber diese> abtipselei will ich mir sparen.
Ansich wurde schon alles gesagt.
Nur noch ein Tip:
Gegen die "abtipselei" gibt es seit jeher in Windows und anderen
Betriebssystemen "copy and paste"
> ich hab mich jetzt fuer die #define variante mit extern entschieden.
Das ist aber trotzdem der falsche Weg. Es gibt einen Unterschied
zwischen der Deklaration (mit extern) und der Definition (ohne extern)
der Variable. Die Deklaration besagt nur, dass es die Variable mit dem
besagten Namen und dem angegebenen Typ irgendwo gibt. Deklarieren kann
man eine Variable, so oft man will. Die Variable existiert deshalb noch
nicht. Die Definition hingegen "erstellt" tatsächlich die Variable, sie
darf deshalb im gesamten Quellcode nur einmal erfolgen. In einer
Header-Datei sollte deshalb nur die Deklaration (mit extern) erfolgen.
Jede .c-Datei, in die die Header-Datei included wird, weiß damit, dass
es die Variable irgendwo gibt. In der main.c würde es sich hier
anbieten, die Variable auch zu definieren. Das ganze deshalb in der
main.c, damit es auch wirklich nur einmal passiert. Würdest du die
Variable in der Header-Datei ohne extern definieren und die Header-Datei
mehrmals in verschiedene .c-Dateien includen, dann würde die Variable
eigentlich für jede .c-Datei neu erstellt. Also jede .c-Datei würde dann
eine andere Variable verwenden, obwohl die gleich heißen. Aber ich glaub
der Linker wird sich trotzdem beschweren, dass es mehrere globale
Variablen mit dem gleichen Namen gibt.
Der Weg von Bertram S. ist der einzig richtige.
Grüße
Randy
Nein, nicht der einzig richtige.
Abgesehen davon, daß da noch in main.c ein #include "main.h" fehlt
(damit der Compiler Abweichungen erkennen kann), ist es
durchaus legitim und wird auch gelegentlich so gemacht, daß
in der Headerdatei die Variable als extern steht, alle *.c
includen diese und in einer (hier wäre das main.c) steht vor dem
#include "main.h" dann ein #define extern, wodurch das extern
bei diesem #include effektiv verschwindet. Das ist mäßig elegant,
aber oft besser (oder als besser erachtet), als Deklaration und
Definition getrennt zu halten.
Man sollte dann aber nach dem #include nicht das #undef extern
vergessen...
Ich will jetzt nicht behaupten, daß das der irrrsinnig tolle Weg
wäre, aber den gibt es in C leider nicht. Irgendwie muß man
zumindest etwas herummurksen.
Klaus Wachtler schrieb:
> [...], daß> in der Headerdatei die Variable als extern steht, alle *.c> includen diese und in einer (hier wäre das main.c) steht vor dem> #include "main.h" dann ein #define extern, wodurch das extern> bei diesem #include effektiv verschwindet. Das ist mäßig elegant,
und es ist nicht mehr möglich, Initializer für die so definierten
Variablen zu schreiben, weil dann da steht
int blubb; // aus min.h
int blubb = 1; // aus main.c
Hier ist m.E. an der falschen Stelle gespart.
Man kann das ganze uebrigens auch ohne extern loesen, indem man
Zugriffsfunktionen benutzt. Braucht natuerlich ein wenig mehr Codespace.
Fuer meinen Geschmack wird in der Mikrocontroller-Welt aber viel zu viel
mit globalen Variablen, die von ueberall her direkt verwendet werden, um
sich geschmissen.
Johann L. (gjlayde) schrieb:
> und es ist nicht mehr möglich, Initializer für die so definierten> Variablen zu schreiben, weil dann da steht>> int blubb; // aus min.h> int blubb = 1; // aus main.c
Doch, geht, ich mache das schon seit über 20 Jahren so:
1
#ifdef IN_MAIN
2
#define EXTERN
3
#define EXT_INIT(x) = x
4
#else
5
#define EXTERN extern
6
#define EXT_INIT(x)
7
#endif
8
9
EXTERNintblubbEXT_INIT(1);
> Hier ist m.E. an der falschen Stelle gespart.
Deine Meinung, nicht meine. Der Vorteil von Deklaration/Definition an
einer einzigen Stelle im Source ist für mich unschlagbar.
Gruß,
Frank
Ich kann mich da nur meinem Vorredner anschliessen und den Zugriff über
Funktionen machen. Globale Variablen auf die von mehreren Modulen
zugegriffen werden ist meines Erachtens schlechter Code, schwer
nachvollziehbar und auch schwer erweiterbar. In meinen Programmen muss
jedes Modul separat compiliert werden können. Damit ist es auch für
weitere Projekte wiederverwehrtbar.
Gruß Thomas
Frank M. schrieb:
> Johann L. (gjlayde) schrieb:>>> und es ist nicht mehr möglich, Initializer für die so definierten>> Variablen zu schreiben, weil dann da steht>> Doch, geht, ich mache das schon seit über 20 Jahren so:>>
1
>#ifdefIN_MAIN
2
>#defineEXTERN
3
>#defineEXT_INIT(x)=x
4
>#else
5
>#defineEXTERNextern
6
>#defineEXT_INIT(x)
7
>#endif
8
>
9
>EXTERNintblubbEXT_INIT(1);
10
>
Frei flottierende, globale und statische Skalare sind ja so ziemlich die
Ausnaheme. Zumindest im meinen C-Anwendungen. Ich hab oben nen int
genommen, um die Problematik aufzuzeigen. IdR wird man in C
zusammengehörende Sachen in einem Komposit zusammenfassen, so daß
zusammen steht, was zusammen gehört. Zudem kann man dann nen Zeiger auf
das "Objekt" übergeben und braucht nicht mit zig Basistypen zu
hantieren.
Beispiel sind etwa Items in Menü-Steuerungen. Dann gehört zu jedem so
definierten Komposit also ein eigenes Initializer-Makro... naja.