ein Kapitel zurück                                           ein Kapitel weiter

Array von Strukturen hört sich auch wieder komplizierter an als es ist. Aber auch hier ist das Prinzip das selben wie schon im Kapitel zuvor, Wertzuweisung von Strukturen läuft genauso ab wie Wertzuweisung von Variablen. Somit ergibts auch hier, Wertzuweisungen von Arrays von Strukturen läuft genauso ab wie Wertzuweisungen von Arrays....

Array von Strukturen


Ich glaube dieses Bild verdeutlicht dies ganze. Natürlich funktioniert die Initialisierung der einzelnen Werte auch hier mit dem Punkteoperator. Ein häufiger Fehler der gemacht wird ist folgende falsche Wertübergabe....

strcpy(lib.titel[1], "Hallo");

Der Variablenname laute ja lib und nicht titel. Wiederum erlaubt wäre folgende Methode....

strcpy(lib[0].titel[3],"x");

Hier würden sie auf das erste Array, der Variable titel dem 3.Buchstaben in der Struktur index zugreifen.

Nun werden sie sich natürlich Fragen wie man es macht damit man mehr Adressen eingeben kann? Die Dynamische Version lernen sie in einem anderen Kapitel kennen. Nun ich habe Ihnen oben beschrieben sich ein Struktur etwa wie eine normale Variable Vorzustellen. Nun wenn Arrays auf Strukturen ummünzt...

char adressen[100];

.........

stuct adres { ......
                       /*Variablen*/
                        ......
                     }adressen[100];

Somit hätten wir eine Struktur in der 100 Adressen Platz haben. Setzen wir das mal in ein Programm um....

/*Download:struct2.c*/
/*struc2.c*/ #include <stdio.h> #include <string.h> #include <stdlib.h> static int x; struct adres { char vname[20]; char nname[20]; long PLZ; char ort[20]; int geburtsjahr; }adressen[100]; void Eingabe(int nr,struct adres neu[]) { printf("Vorname : "); gets(neu[nr].vname); printf("Nachname : "); gets(neu[nr].nname); printf("Postleitzahl: "); scanf("%ld",&neu[nr].PLZ); fflush(stdin); printf("Wohnort : "); gets(neu[nr].ort); printf("Geburtsjahr : "); scanf("%d",&neu[nr].geburtsjahr); } void Suche(struct adres search[],char buchstabe,int nr) { int i; for(i=0; i<=nr; i++) { if(search[i].nname[0] == buchstabe) { printf("\n\nGefunden unter Buchstabe :\"%c\"\n\n",buchstabe); printf("Vorname.........:%s\n",search[i].vname); printf("Nachname........:%s\n",search[i].nname); printf("Postleitzahl....:%ld\n",search[i].PLZ); printf("Ort.............:%s\n",search[i].ort); printf("Geburtsjahr.....:%d\n",search[i].geburtsjahr); fflush(stdin); printf("\n\tWeiter mit <ENTER>\n"); getchar(); } } } void Ausgabe(struct adres all[],int nr) { int i; for(i=0; i<nr; i++) { printf("Vorname.........:%s\n",all[i].vname); printf("Nachname........:%s\n",all[i].nname); printf("Postleitzahl....:%ld\n",all[i].PLZ); printf("Ort.............:%s\n",all[i].ort); printf("Geburtsjahr.....:%d\n\n",all[i].geburtsjahr); if((!(i%2))&& i!=0) { fflush(stdin); printf("\n\tWeiter mit <Enter>\n\n"); getchar(); } } } void Sort(struct adres sort[],int nr) { int i,j; struct adres *temp; temp=(struct adres *)malloc(sizeof(struct adres *)); for(i=0; i<nr; i++) { for(j=i+1;j<nr;j++) { if(strcmp(sort[i].nname, sort[j].nname)>0) { *temp=sort[j]; sort[j]=sort[i]; sort[i]=*temp; } } } printf(".....Sortiert!!\n\n"); } int main() { int auswahl; char c; do { printf("-1- Neue Adresse eingeben\n"); printf("-2- Bestimmte Adresse Ausgeben\n"); printf("-3- Alle Adressen Ausgeben\n"); printf("-4- Adressen Sortieren\n"); printf("-5- Programm beenden\n"); printf("\nIhre Auswahl : "); scanf("%d",&auswahl); fflush(stdin); switch(auswahl) { case 1 : Eingabe(x++,adressen); break; case 2 : printf("Anfangsbuchstabe d. Nachnamen :"); scanf("%c",&c); Suche(adressen,c,x); break; case 3 : Ausgabe(adressen,x); break; case 4 : Sort(adressen,x); break; default: break; } }while(auswahl <5); return 0; }

Auf dem 1.Blick sieht das Programm recht schwierig aus, aber lassen sie sich nicht täuschen und gehen sie es in Ruhe durch. Springen wir gleich bei der 1. Funktion unseres Programms ein...

Eingabe(x++,adressen);

Hiermit rufen wir die Funktion 'Eingabe()' zum Eingeben unseres Adresssatzes. Wir übergeben die Parameter 'x' den wir global mit static deklariert haben. Wir erhöhen 'x' gleich bei der Übergabe um den Wert 1. Des weiteren übergeben wir an die Funktion die Variable 'adressen' vom Typ 'struct adres'. Unsere Funktion sieht dann folgendermaßen aus....

void Eingabe(int nr,struct adres neu[])

Nun wollen wir der Struktur Namens 'neu' alias 'adressen' den 1. Adresssatz übergeben. Zuerst der Vorname.....

printf("Vorname : ");
gets(neu[nr].vname);

Mit gets tippen sie den Vorname des 1. Adresssatzes ein. Das würde intern etwa so aussehen...

neu[1].vname = "Name" 

....oder genauer....

adressen[1].vname = "Name"

Genauso geben sie dann die nächsten Daten ein. Nach der Eingabe können sie jetzt einen 2.Adresssatz eingeben. Wenn sie jetzt z.B. den Nachnamen des 20. Adresssatzes wollen, greifen sie so darauf zu....

printf("%s",adressen[19].nname);

Kommen wir zur 2. Funktion unseres Programms...

printf("Anfangsbuchstabe d. Nachnamen :"); 
scanf("%c",&c);
Suche(adressen,c,x);

Hier haben wir eine Funktion zur Suche bestimmter Nachnamen den wir mit dem von Ihnen eingegebenen Anfangsbuchstaben suchen. Der Funktion übergeben wir als Parameter 'adressen' vom Typ 'struct adres', dann übergeben wir den von Ihnen soeben eingegebenen Anfangsbuchstaben und 'x' für die Anzahl unserer bisher eingegebenen Adressen. Auf die Variable 'x' als Parameterübergabe könnten wir theoretisch verzichten da wir 'x' eigentlich Global definiert haben. Ok nun zu unserer Funktion...

void Suche(struct adres search[],char buchstabe,int nr)

Die Suche selber erweist als einfach zu realisieren.....

for(i=0; i<=nr; i++)
   {
     if(search[i].nname[0] == buchstabe)
     .........................

Mit der for - Schleife zählen wir die Anzahl der Adressen hoch um jeden Adresssatz mit dem Eingegebenen Buchstaben zu vergleichen. Als Beispiel nehmen wir an sie suchen alle Namen die mit dem Buchstaben 'M' beginnen wird unser Programm folgendermaßen ablaufen....

for...i=0
if(search[0].nname[0] == 'M')
falls ja werden dessen Daten ausgegeben
for..i++ ..i<=nr
if(search[1].nname[0] == 'M')
falls ja werden dessen Daten ausgegeben
for..i++..i<=nr
................
................

Wir vergleichen bei dem Nachnamen nur den 1.Buchstaben mit dem Indexfeld ..nname[0]. 0 ist der 1.Buchstabe! Falls sie ganze Namen suchen wollen wird die Sache auch nicht viel schwerer. Sie benötigen lediglich die strcmp - Funktion.

Die Funktion 'Ausgabe' ist eigentlich nichts mehr neues. Hier zählen wir wieder mit Hilfe der for - Schleife den Indexzähler [i] hoch um alle vorhandenen Adressen auf dem Bildschirm auszugeben.

Etwas schwieriger dürfte sich jetzt für Ihnen die Sortierfunktion darstellen...

void Sort(struct adres sort[],int nr)

Was Ihnen wahrscheinlich etwas unklar sein wird ist...

struct adres *temp;
temp=(struct adres *)malloc(sizeof(struct adres *));

Zuerst definieren wir ein weiter Struktur Namens 'temp' vom Typ 'struct adres'. Diese Struktur hat aber jetzt nichts mit der Struktur mit dem Namen 'adressen' zu tun. Nochmals zur Erinnerung, 'int a' ist auch nicht das selbe wie 'int b'. Wir benutzen hier einen Zeiger denn unsere neue Struktur soll lediglich auf die Anfangsadresse unserer Struktur zeigen. '*temp' dient lediglich als Zwischenspeicher zum Austauschen zweier Strukturen. Zur Sicherheit das wir auf '*temp' zwischenspeichern können, reservieren wir dafür Speicher der Größe unserer Struktur 'struct adres'. Anschließend Sortieren wir unsere Struktur mir...

for(i=0; i<nr; i++)
   {
     for(j=i+1;j<nr;j++)
       {
         if(strcmp(sort[i].nname, sort[j].nname)
           {
             *temp=sort[j];
              sort[j]=sort[i];
              sort[i]=*temp;
           }
           .......................

Hier sortieren wir wieder nach dem Motto zuerst das kleinste Element dann das Zweitkleinste u.s.w....

wir haben z.B 4 Namen zum sortieren:

if(strcmp(sort[0].nname, sort[1].nname)
falls sort[0].nname größer als sort[1].name !tauschen!
if(strcmp(sort[0].nname, sort[2].nname)
falls sort[0].nname größer als sort[2].name !tauschen!
if(strcmp(sort[0].nname, sort[3].nname)
falls sort[0].nname größer als sort[3].name !tauschen!
if(strcmp(sort[1].nname, sort[2].nname)
falls sort[1].nname größer als sort[2].name !tauschen!
if(strcmp(sort[1].nname, sort[3].nname)
falls sort[1].nname größer als sort[3].name !tauschen!
if(strcmp(sort[2].nname, sort[3].nname)
falls sort[2].nname größer als sort[3].name !tauschen!

......Sortiert!

Nun hat diese Möglichkeit von Strukturen mit Arrays folgenden Nachteil. Was machen sie wenn sie bereits 100 Adressen eingegeben haben? Sicherlich es es gibt da ein paar Tricks ein Array während der Laufzeit zu ändern! Aber dies ist Umständlich und Zeitaufwendig. Wenn wir jetzt z.B. eine Struktur mit 1000 Elementen definiert haben und unsere Struktur sortieren müssen, müssen wir ständig ganze Strukturen hin. - und - herkopieren. Dabei bleibt die Performance ziemlich auf der Strecke. Und wenn ich Ihnen in einem Fortgeschrittenen Kapitel zeige wie sie Felder "dynamisch" machen können. Benötigen wir außer der Struktur mit 1000 Elementen nochmals eine Struktur mit 1000 Elementen um unsere Struktur zwischenzuspeichern. Aber wenn man nur kleinere Adressdatenbanken benötigt dürfte dies nicht so gravierend sein.

Ich belasse es jetzt mit dem Einstieg in die Welt der Datenstrukturen in C. In den folgenden Kapiteln werden wir das Thema Schritt für Schritt besser machen.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf