B.11 Antworten und Lösungen zu Kapitel 12
-
Mit Strukturen erstellen Sie einen eigenen zusammengesetzten Datentyp, der mehrere Komponentenvariablen mit gleichen und/oder unterschiedlichen Typen zu einem neuen Datentyp zusammenfasst. Bei der Deklaration von Strukturen wird das Schlüsselwort struct verwendet. Die gleichen oder unterschiedlichen Datentypen werden zwischen geschweiften Klammern zusammengefasst und als Komponenten bzw. Strukturelemente bezeichnet. Abgeschlossen wird die Deklaration mit einem Semikolon. Zugreifen kann man auf die einzelnen Komponenten mit dem Punktoperator (.). Wenn es sich bei der Strukturvariablen um Zeiger handelt, nutzen Sie den Pfeiloperator (->).
-
Unions sind den Strukturen recht ähnlich. Der Zugriff erfolgt genauso, allerdings mit dem Unterschied, dass bei Unions die einzelnen Elemente nicht hintereinander im Speicher liegen, sondern alle mit derselben Anfangsadresse beginnen. Das bedeutet, dass immer nur ein Element in einer Union mit einem gültigen Wert belegt werden kann. War ein anderes Element bereits mit einem Wert versehen, wird dieser überschrieben. Eine Union ist also nur so groß wie das größte Element in der Union. Anstatt des Schlüsselwortes struct wird bei einer Union das Schlüsselwort union verwendet.
-
Die Strukturvariable in Zeile (06) erstellen Sie, indem Sie das Schlüsselwort struct voranstellen. Wollen Sie Zeile (06) so verwenden, wie es im Beispiel angegeben ist, müssen Sie zusätzlich typedef verwenden. Hier das korrekte Beispiel mit typedef:
01 typedef struct artikel {
02 char schlagzeile[255];
03 int seite;
04 int ausgabe;
05 } Artikel;
...
06 Artikel artikel1; // Jetzt klappt es auch ohne Fehlermeldung
07 // des Compilers. -
Der erste Fehler wurde in Zeile (15) gemacht. Dort wurde die Struktur sofort mit Werten initialisiert. Hierbei wurde aber die richtige Reihenfolge der einzelnen Strukturelemente nicht beachtet, und dies wird der Compiler bemängeln. Der zweite Fehler wurde in den Zeilen (18) bis (20) gemacht. Dort wurde mit einem Strukturzeiger auf die Strukturelemente zugegriffen, obwohl vorher gar kein Speicher für eine solche Struktur reserviert wurde. In dem letzten Beispiel wurde daher in Zeile (16) ein dynamischer Speicherblock auf dem Heap reserviert. Zwar wurde hier der Einfachheit halber auf eine Überprüfung verzichtet, ob der Speicherblock auch reserviert werden kann, in der Praxis sollten Sie dies bei komplexeren Projekten aber tun. Den dritten und letzten Fehler finden Sie in den Zeilen (21) bis (23). Dort wurde der Indexoperator ([]) des Struktur-Arrays mit einer falschen Positionsangabe verwendet. Es folgt das lauffähige Listing mit den behobenen Fehlern:
00 // kap012/loesung001.c
01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <string.h>
04 typedef struct artikel{
05 char schlagzeile[255];
06 int seite;
07 int ausgabe;
08 } Artikel;
09 void output( Artikel *a ) {
10 printf("%s\n", a->schlagzeile);
11 printf("%d\n", a->seite);
12 printf("%d\n\n", a->ausgabe);
13 }
14 int main(void) {
15 Artikel art1 = {"Die Schlagzeile schlechthin",244, 33};
16 Artikel *art2 = malloc(sizeof(Artikel));
17 Artikel artArr[2];
18 strncpy( art2->schlagzeile, "Eine Schlagzeile", 255);
19 art2->seite = 212;
20 art2->ausgabe = 43;
21 strncpy( artArr[0].schlagzeile, "Noch eine", 255);
22 artArr[0].seite = 266;
23 artArr[0].ausgabe = 67;
24 output( &art1 );
25 output( art2 );
26 output( &artArr[0] );
27 return EXIT_SUCCESS;
28 } -
Sie sehen nachfolgend eine Musterlösung. Die Funktion gibt 0 zurück, wenn beide Strukturen gleich sind; ansonsten wird 1 zurückgegeben:
00 // kap012/loesung002.c
01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <string.h>
04 typedef struct artikel{
05 char schlagzeile[255];
06 int seite;
08 int ausgabe;
09 } Artikel;
10 int ArtikelCmp( Artikel *art1, Artikel *art2 ) {
11 if( strcmp(art1->schlagzeile, art2->schlagzeile) ) {
12 return 1;
13 }
14 else if( art1->seite != art2->seite ) {
15 return 1;
16 }
17 else if( art1->ausgabe != art2->ausgabe ) {
18 return 1;
19 }
20 return 0;
21 }
22 int main(void) {
23 Artikel art1 = {"Die Schlagzeile schlechthin", 244, 33};
24 Artikel art2 = {"Die Schlagzeile schlechthin", 244, 33};
25 Artikel art3 = {"Die Schlagzeile_schlechthin", 244, 33};
26 if( ArtikelCmp( &art1, &art2 ) ) {
27 printf("art1 und art2 sind nicht gleich\n");
28 }
29 if( ArtikelCmp( &art2, &art3 ) ) {
30 printf("art2 und art3 sind nicht gleich\n");
31 }
32 return EXIT_SUCCESS;
33 }