Das wichtigste Prinzip ist wohl das hier:
C an sich, hat keine Projektverwaltung!
Wenn sich der Compiler eine C-Datei vornimmt, dann interessiert ihn
nicht, was in anderen C-Dateien steht. Jede C-Datei wird für sich und
unabhängig von allen anderen übersetzt. Jede Datei muss in sich
vollständig sein.
Da der Compiler bei diesem Quelltext
1 | int main(){
|
2 | {
|
3 | Uhrzeit.Minuten = 5;
|
4 | }
|
weder jemals irgendetwas von einer Variable 'Uhrzeit', noch deren
Aufbau, noch dass sie einen Member 'Minuten' hat gehört hat, setzt es
einen Fehler.
Also musst du ihm erst mal klar machen, dass es eine Variable Uhrzeit
gibt. Du brauchst eine Deklaration dafür
1 | extern volatile datestruct Uhrzeit;
|
2 |
|
3 | int main(){
|
4 | {
|
5 | Uhrzeit.Minuten = 5;
|
6 | }
|
Tja. Alles schön gut. Aber was ist jetzt wieder ein 'datestruct'?
Da der Compiler das nur durch betrachten dieses Textes nicht wissen
kann, muss man ihm das mitteilen
1 | typedef struct
|
2 | {
|
3 | volatile unsigned char Sekunden;
|
4 | volatile unsigned char Minuten;
|
5 | volatile unsigned char Stunden;
|
6 | } datestruct;
|
7 |
|
8 | extern volatile datestruct Uhrzeit;
|
9 |
|
10 | int main(){
|
11 | {
|
12 | Uhrzeit.Minuten = 5;
|
13 | }
|
Und jetzt ist man in der unschönen und unglücklichen Lage, dass man in 2
C-Files dieselbe Strukturdefinition hat. Das will man auf alle Fälle
vermeiden!
Die Lösung: Man verbannt die Strukturdefinition (und die extern
Deklaration gleich mit) in ein Header File
rtc.h
*****
1 | typedef struct
|
2 | {
|
3 | volatile unsigned char Sekunden;
|
4 | volatile unsigned char Minuten;
|
5 | volatile unsigned char Stunden;
|
6 | } datestruct;
|
7 |
|
8 | extern volatile datestruct Uhrzeit;
|
wird dieses in main.c inkludiert
1 | #include "rtc.h"
|
2 |
|
3 | int main(){
|
4 | {
|
5 | Uhrzeit.Minuten = 5;
|
6 | }
|
dann ist alles paletti. Durch den include wird die Definition von
'datestruct' hereingezogen und auch gleich noch die extern-Deklaration
von Uhrzeit.
Und in rtc.c mach ich (fast) dasselbe
1 | #include "rtc.h"
|
2 |
|
3 | volatile datestruct Uhrzeit;
|
4 |
|
5 | void foo()
|
6 | {
|
7 | }
|
Damit hab ich erreicht, dass es die Strukturdefinition nur einmal in
Textform gibt und somit ist sichergestellt, dass sie an allen Stellen
gleich aussieht.
Eigentlich ganz einfach.