Strukturen
In einer Struktur kann eine beliebige Anzahl von Komponenten (Daten) mit unterschiedlichen Datentypen (im Gegensatz zu Feldern) zusammengefaßt werden.
Der Programmierer hat also hier das erste Mal die Möglichkeit neben den fest vorgegebenen Datentypen wie int, char, usw. selbst eigene Datentypen zu basteln bzw. zu entwerfen.
Syntax:
struct Bezeichner { Datentyp1 Bezeichner1; Datentyp2 Bezeichner2; ....};
Beispiel:
struct dtadresse{ char strasse[20]; char ort[20]; int plz; };
struct dtdatum{ int tag; int monat; int jahr; };
int main(){
// gleich geht es weiter
Deklaration der Struktur dtadresse
Es wird noch keine Variable angelegt (Speicher reserviert).
Deklaration der Struktur dtdatum
Es wird noch keine Variable angelegt (Speicher reserviert).
Die Semikolons sind nötig, sonst Fehlermeldung des
Compilers.
struct dtadresse{ char strasse[20]; char ort[20]; int plz; };
struct dtdatum{ int tag; int monat; int jahr; };
int main(){
// gleich geht es weiter
Hier wird an den Anfang eines jeden Strukturnamens dt (wie datentyp) geschrieben. Falls
jemand ein besseres Namensvergabesystem
vorschlagen will, der wird gebeten, dies bitte zu machen.
PS: Dem Compiler ist die Namensvergabe relativ egal!
struct dtadresse{ char strasse[20]; char ort[20]; int plz; };
struct dtdatum{ int tag; int monat; int jahr; };
int main(){
// gleich geht es weiter
Wir deklarieren alle Strukturen am Anfang (vor allen
Funktionen), damit sie allen Funktionen bekannt sind und
deshalb von ihnen benutzt werden können (z.B. also lokale
Variablen).
struct dtadresse a1;struct dtadresse a2 = {"rosenweg","stuttgart",74123};struct dtdatum d1;struct dtdatum d2 = {7,4,1947};
Deklaration der Variablen a1:Es wird eine Variable angelegt
(Speicher reserviert).
Deklaration + Initialisierung der Variablen a2:
Es wird eine Variable angelegt (Speicher reserviert) + den
einzelnen Komponenten Werte zugewiesen
Deklaration der Variablen d1:Es wird eine Variablen
angelegt (Speicher reserviert).
Deklaration + Initialisierung der
Variablen d2
struct dtadresse a1;struct dtadresse a2 = {"rosenweg","stuttgart",74123};struct dtdatum d1;struct dtdatum d2 = {7,4,1947};
Welchen Datentyp hat a1 und a2 ?
Welchen Datentyp hat d1 und d2 ?
dtadresse
dtdatum
struct dtadresse a1;struct dtadresse a2 = {"rosenweg","stuttgart",74123};struct dtdatum d1;struct dtdatum d2 = {7,4,1947};
Wie viel Speicher wird für die Variable a1 reserviert ?
Speicherplatz char strasse[20] +Speicherplatz char ort [20] +
Speicherplatz int plz = 44 Byte
Wie viel Speicher wird für die Variable d1 reserviert ?
Speicherplatz int tag +Speicherplatz int monat +
Speicherplatz int jahr = 12 Byte
struct dtadresse a1;struct dtadresse a2 = {"rosenweg","stuttgart",74123};struct dtdatum d1;struct dtdatum d2 = {7,4,1947};a1.ort[0]='U';a1.ort[1]='l';a1.ort[2]='m';a1.ort[3]='\0';
Auf die einzelnen Komponenten einer Struktur
kann mit dem Punkt . zugegriffen werden
Wie speichert man in d1 das Datum von Sylvester 2003 ?
Wie speichert man in a1 die Postleitzahl 72631?
Wie speichert man in a2 den Ort Urach ?
a1.plz = 72631;d1.tag = 31;d1.monat = 12;d1.jahr = 2003;strcpy(a2.ort, "Urach");
oder alternativ: wie oben
Strukturen können ihrerseits wieder Strukturen als
Komponenten enthalten:
struct dtadresse{ char strasse[20]; char ort[20]; int plz; }; struct dtdatum{ int tag; int monat; int jahr; };
struct dtperson{ char name[20]; struct dtadresse adresse; struct dtdatum datum; };int main(){
Deklaration der Struktur dtperson
Die Struktur dtperson enthält die Strukturen dtadresse und dtdatum als Komponenten.
struct dtadresse a1;struct dtadresse a2 = {"rosenweg","stuttgart",74123};struct dtdatum d1;struct dtdatum d2 = {7,4,1947};struct dtperson p1;struct dtperson p2 = {"maier",{"seeweg","urach",74324}, {8, 7, 1967}};
Deklaration der Variablen p1:Es wird eine Variable angelegt
(Speicher reserviert).
Deklaration + Initialisierung der Variablen p2:Es wird eine Variable angelegt (Speicher reserviert) + den einzelnen
Komponenten Werte zugewiesen
struct dtadresse a1;struct dtadresse a2 = {"rosenweg","stuttgart",74123};struct dtdatum d1;struct dtdatum d2 = {7,4,1947};struct dtperson p1;struct dtperson p2 = {"maier",{"seeweg","urach",74324}, {8, 7, 1967}}; p1.adresse.plz = 72669;
Auf die Komponente einer mehrfach verschachtelten Struktur wird mit mehreren Punkten . zugegriffen.
struct dtadresse a1;struct dtadresse a2 = {"rosenweg","stuttgart",74123};struct dtdatum d1;struct dtdatum d2 = {7,4,1947};struct dtperson p1;struct dtperson p2 = {"maier",{"seeweg","urach",74324}, {8, 7, 1967}}; p1.adresse.plz = 72669;p1.datum.tag = 24;p1.datum.monat = 12;p1.datum.jahr = 2000;
Wie setzt man das Datum in der
Variablen p1 auf Weihnachten 2000 ?
Funktionen und Strukturen:
Eine Struktur kann auch als formaler Parameter in einer Funktion benutzt werden.
Beispiel (Input-Parameter)
void printDatum(struct dtdatum pd){ printf("Tag=%d\n",pd.tag); printf("Monat=%d\n",pd.monat); printf("Jahr=%d\n",pd.jahr);}
Ist der formale Parameter pd ein input- (call by value) oder ein output- (call by
reference) Parameter ?
Er ist ein input-Parameter, weil über ihn nichts aus der Funktion
zurückgeliefert wird.
Beispiel mit Aufruf kommt nachher !
Die Funktion changeDatum soll den Tag, Monat und das Jahr in einer Strukturvariablen setzen.Welche Parameter werden benötigt und welche Aufgabe (input, output) haben sie ?
void changeDatum(struct dtdatum *pd, int t, int m, int j){ (*pd).tag = t;
(*pd).monat = m;
(*pd).jahr = j;
}
Input-Parameter
Output-Parameter pd (ist eine Adresse)Das Datum der Variablen pd wird verändert:
Das Datum wird überschrieben.
void changeDatum(struct dtdatum *pd, int t, int m, int j){ (*pd).tag = t;
(*pd).monat = m;
(*pd).jahr = j;
}
Stattdessen wird oft:
pd->tag = t;
pd->monat = m;
pd->jahr = j;
dieser Ausdruck verwendet
Mit dem Operator -> kann genauso auf die einzelnen Elemente der Struktur zugegriffen
werden:(*pd).tag
ist gleichwertig zu pd->tag
Beispiel (Funktion und Aufruf)
int main(){ struct dtdatum d2 = {7,4,1947};
}
void changeDatum(struct dtdatum *pd, int t, int m, int j){ // siehe frühere Folie}
void printDatum(struct dtdatum pd){ // siehe frühere Folie}
changeDatum(&d2, 17, 8, 1956);printDatum(d2);
Mit welchen 2 Aufrufen (Funktionsaufrufe) wird das Datum in d2 auf den 17.8.1956 gesetzt und dann auf dem Bildschirm ausgegeben ?
Welchen kleinen Fehler hat das Programm noch ?
Warum meldet der Compiler einen Fehler ?
Die Struktur dtdatum muß noch deklariert werden. Diese Deklaration darf aber nicht innerhalb von main geschehen, da diese Deklaration dann nicht der Funktion changeDatum bekannt wäre.
Deshalb muß dies außerhalb von main und allen anderen
Funktionen geschehen !Dies gilt genauso für die
Deklarationen der Funktionen.
struct dtdatum{ int tag; int monat; int jahr;};void printDatum(struct dtdatum pd);void changeDatum(struct dtdatum *pd, int t, int m, int j);
int main(){ struct dtdatum d2 = {7, 4, 1947}; changeDatum(&d2, 7, 8, 1956); printDatum(d2); return 0;}
void changeDatum(struct dtdatum *pd, int t, int m, int j){ pd->tag = t; pd->monat = m; pd->jahr = j;}// Was fehlt noch ?
void printDatum(struct dtdatum pd){printf("Tag=%d\n",pd.tag);printf("Monat=%d\n",pd.monat);printf("Jahr=%d\n",pd.jahr);
}
Die Funktion erhoeheJahr soll das Jahr in einer Strukturvariablen um 1 erhöhen.Welche Parameter werden benötigt und welche Eigenschaften (input, output) haben sie ?
void erhoeheJahr(struct dtdatum *pd){ (*pd).jahr = (*pd).jahr + 1;
}
// (*pd).jahr++;// pd->jahr = pd->jahr + 1;// pd->jahr++;
// Alternativ dazu möglich wäre:
Dieser Parameter wird als input benötigt, weil man die Komponente jahr in pd um 1 erhöhen will).
Dieser Parameter wird auch als output verwendet, weil man hier die veränderte Strukturvariable pd (in der die Komponente jahr um 1 erhöht wurde) zurückgibt. Dieser Parameter ist also ein Input/Output-Parameter.
void erhoeheJahr(struct dtdatum *pd){ (*pd).jahr = (*pd).jahr + 1;
}
// (*pd).jahr++;// pd->jahr = pd->jahr + 1;// pd->jahr++;
// Alternativ dazu möglich wäre:
Kann z.B. die Klammer bei (*pd).jahr weggelassen werden ?Wie groß ist die Priorität der einzelnen Operatoren ?
( ) . –> ++ (Assoziativität: links -> rechts)hat höhere Priorität (bindet stärker) als (siehe Hilfe) * (Assoziativität: rechts -> links)