lightninglord wrote:
>
>
1 | extern short2bytes Anzeige;
|
>
> in meine ausgelagerte .c bekomme. Könnt ihr mir bitte nochmal helfen,
> bin fast am verzweifeln.
Du musst dir immer eines vergegenwärtigen.
Wenn er Compiler eine *.c Datei compiliert, dann kennt er nur
diese eine Datei. Es ist völlig unerheblich, was in anderen
*.c Dateien steht, es wird nur das berücksichtigt was in dieser
einen Datei steht. C kennt keinen Projektgedanken wie ihn andere
Sprachen haben.
Der Compiler geht deinen Code von oben nach unten durch. Alles
was verwendet wird, muss vor der Verwendung definiert werden.
Wenn der Compiler short2bytes nicht kennt, dann deshalb, weil
es nicht vor der Verwendung in diesem .c File* definiert
wurde. Es ist völlig unerheblich, ob diese union in einer anderen
*.c definiert ist. Der Compiler compiliert jetzt dieses File
und nur der Inhalt dieses Files wird untersucht.
Daher werden solche unions oder Strukturen auch in Header Files
ausgelagert, damit man immer die gleiche Strukturdefinition in
das jeweilige *.c File inkludieren kann. Inkludieren ist genauso-
gut, wie wenn du das direkt hingeschrieben hättest. Im Grunde
passiert eigentlich sogar genau das: Der Quelltext den du geschrieben
hast, wird vor dem eigentlichen compilieren nochmal modifiziert.
Genauso wie du es mit deinem Texteditor machen würdest, wenn du
die #include Zeile mit dem Inhalt der angegebenen Datei ersetzt.
Also machst du dir erst mal ein Header File, in dem alles notwendige
enthalten ist. Dazu gehört selbstverständlich auch die Definition
deiner Struktur
Definition.h
************
1 | typedef union {
|
2 |
|
3 | unsigned short all;
|
4 |
|
5 | struct {
|
6 |
|
7 | unsigned char low;
|
8 | unsigned char high;
|
9 |
|
10 | };
|
11 |
|
12 | } short2bytes;
|
13 |
|
14 | extern short2bytes Anzeige;
|
Dieses Header File ist für sich alleine genommen vollständig.
Eine Variable 'Anzeige' wird deklariert (extern, dazu gleich später
mehr), und auch was es mit dem Datentyp short2bytes auf sich hat
ist da drinn enthalten.
Das heist, wenn du dieses Header File irgendwo inkludierst, dann
bringt dieses Header File alles mit, was gebraucht wird um die
Deklaration von 'Anzeige' machen zu können.
zb.
Test1.c
*******
1 | #include "Definition.h"
|
2 |
|
3 | void Funktion1()
|
4 | {
|
5 | Anzeige.all = 5;
|
6 | }
|
Wenn der Compiler dieses Test.c übersetzt, dann kommt zuerst der
Preprozessor zum Zug, der die include Zeile mit dem Inhalt der
Datei Definition.h ersetzt. Das Ergebnis ist dann
1 | typedef union {
|
2 |
|
3 | unsigned short all;
|
4 |
|
5 | struct {
|
6 |
|
7 | unsigned char low;
|
8 | unsigned char high;
|
9 |
|
10 | };
|
11 |
|
12 | } short2bytes;
|
13 |
|
14 | extern short2bytes Anzeige;
|
15 |
|
16 | void Funktion1()
|
17 | {
|
18 | Anzeige.all = 5;
|
19 | }
|
20 | [C]
|
21 |
|
22 | Wie du dich überzeugen kannst, ist jetzt in dieser Compiliereinheit
|
23 | alles enthalten, was der Compiler braucht um sie übersetzten zu
|
24 | können. Nichts ist undefiniert. Von jedem Nicht-C-Schlüsselwort,
|
25 | insbesondere von der union gibt es eine Definition und wenn man
|
26 | diese Übersetzungseinheit ansieht und von oben nach unten durchliest,
|
27 | dann wird alles erklärt (definiert) bevor es verwendet wird.
|
28 |
|
29 | Nun kommt aber im Header File, und damit auch in jeder Übersetzungs-
|
30 | einheit die dieses includiert, eine Variable
|
31 | [C]
|
32 | extern short2bytes Anzahl;
|
vor. Das 'extern' bedeutet an dieser Stelle einfach nur: Diese
Variable existiert irgendwo. Wo genau ist an dieser Stelle nicht
wichtig. Es reicht, dass der Compiler weiss, dass es sie gibt und
dass daher die Verwendung einer Variablen 'Anzahl' kein Tippfehler
ist sondern dass es diese Variable tatsächlich irgendwo gibt.
Nur: Irgendwo muss es diese Variable dann aber auch tatsächlich
geben. In einem, und nur in einem, *.c File muss diese Variable
auch tatsächlich angelegt werden. Nun, meistens macht man das
in dem *.c File, in dem auch main() ist. Das ist aber nur eine
Konvention, dass muss nicht unbedingt so sein.
Aber lass uns das mal so machen.
Damit die Variable auch tatsächlich erzeugt werden kann, muss
natürlich der Datentyp short2bytes an der Stelle der Variablen-
definition bekannt sein. Wo kriegen wir den her? Na, ganz einfach.
Indem 'Definitionen.h' inkludiert wird, denn dort steht ja die
Definition dieses Datentyps drinnen
main.c
******
1 | #include "Definitionen.h"
|
2 |
|
3 | short2bytes Anzeige;
|
4 |
|
5 | int main()
|
6 | {
|
7 | Anzeige = 5;
|
8 | }
|
Auch hier wieder. Bevor sich der Compiler diesen Quelltext vornimmt
kommt erst mal der Preprozessor zum Zug, der den include durch
den Inhalt der Datei ersetzt. Aus deinem Quelltext wird so
als Zwischenstufe:
1 | typedef union {
|
2 |
|
3 | unsigned short all;
|
4 |
|
5 | struct {
|
6 |
|
7 | unsigned char low;
|
8 | unsigned char high;
|
9 |
|
10 | };
|
11 |
|
12 | } short2bytes;
|
13 |
|
14 | extern short2bytes Anzeige;
|
15 |
|
16 | short2bytes Anzeige;
|
17 |
|
18 | int main()
|
19 | {
|
20 | Anzeige = 5;
|
21 | }
|
Und auch hier wieder: Wenn du das Programm von oben nach unten
durchgehst, ist alles vor seiner Verwendung definiert worden.
Dass es hier die Sequenz gibt
1 | extern short2bytes Anzeige;
|
2 |
|
3 | short2bytes Anzeige;
|
mag zwar auf den ersten Blick seltsam aussehen, stört aber nicht
weiter. Die erste Zeile (die mit dem extern) ist eine Deklaration
und sagt als solches aus: Irgendwo gibt es ... Die zweite Zeile
hingegen sagt umgangssprachlich aus: Und hier ist sie!