Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
Vorwort des Gutachters
1 Einstieg in C
2 Das erste Programm
3 Grundlagen
4 Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«
5 Basisdatentypen
6 Operatoren
7 Typumwandlung
8 Kontrollstrukturen
9 Funktionen
10 Präprozessor-Direktiven
11 Arrays
12 Zeiger (Pointer)
13 Kommandozeilenargumente
14 Dynamische Speicherverwaltung
15 Strukturen
16 Ein-/Ausgabe-Funktionen
17 Attribute von Dateien und das Arbeiten mit Verzeichnissen (nicht ANSI C)
18 Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
19 Zeitroutinen
20 Weitere Headerdateien und ihre Funktionen (ANSI C)
21 Dynamische Datenstrukturen
22 Algorithmen
23 CGI mit C
24 MySQL und C
25 Netzwerkprogrammierung und Cross–Plattform-Entwicklung
26 Paralleles Rechnen
27 Sicheres Programmieren
28 Wie geht’s jetzt weiter?
A Operatoren
B Die C-Standard-Bibliothek
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch
Buch: C von A bis Z

C von A bis Z
3., aktualisierte und erweiterte Auflage, geb., mit CD und Referenzkarte
1.190 S., 39,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1411-7
Pfeil 15 Strukturen
Pfeil 15.1 Struktur deklarieren
Pfeil 15.2 Initialisierung und Zugriff auf Strukturen
Pfeil 15.3 Strukturen als Wertübergabe an eine Funktion
Pfeil 15.4 Strukturen als Rückgabewert einer Funktion
Pfeil 15.5 Strukturen vergleichen
Pfeil 15.6 Arrays von Strukturen
Pfeil 15.7 Strukturen in Strukturen (Nested Structures)
Pfeil 15.8 Kurze Zusammenfassung zu den Strukturen
Pfeil 15.9 Unions
Pfeil 15.10 Der Aufzählungstyp »enum«
Pfeil 15.11 Typendefinition mit »typedef«
Pfeil 15.12 Attribute von Strukturen verändern (nicht ANSI C)
Pfeil 15.13 Bitfelder
Pfeil 15.14 Das »offsetof«-Makro


Rheinwerk Computing - Zum Seitenanfang

15.6 Arrays von Strukturen topZur vorigen Überschrift

Bei Arrays von Strukturen gilt dasselbe Prinzip wie im Abschnitt zuvor dargestellt. Die Wertzuweisung funktioniert ebenfalls wie bei den normalen Arrays, nämlich mithilfe des Indizierungsoperators ([]). Hierzu ein Beispiel:

/* struct_arr1.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct index {
   int seite;
   char titel[30];
};

int main(void) {
   int i;
   struct index lib[3];

   lib[0].seite=312;
   strcpy(lib[0].titel, "Arrays von Strukturen");
   lib[1].seite=320;
   strcpy(lib[1].titel, "Strukturen in Strukturen");
   lib[2].seite=900;
   strcpy(lib[2].titel, "Anhang");

   for(i=0; i<3; i++)
      printf("Seite %3d\t %-30s\n", lib[i].seite, lib[i].titel);
   return EXIT_SUCCESS;
}

Abbildung 15.4 Array von Strukturen

Abbildung 15.4 verdeutlicht dies nochmals. Auch hierbei erfolgt die Initialisierung der einzelnen Werte über den Punktoperator. Ein Fehler, der dabei oft gemacht wird, ist folgende falsche Wertübergabe:

// falsche Position des Feldindex
strcpy(lib.titel[1], "Hallo");         //falsch

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

Der Variablenname der Struktur lautet schließlich lib und nicht titel.

Jetzt soll das Listing zur Adressverwaltung erweitert werden. Diesmal wird das Programm so umgeschrieben, dass es mit Arrays von Strukturen ausgeführt wird:

struct adres {
   /*Variablen*/
} adressen[100];

In dieser Struktur von Arrays lassen sich somit 100 Daten von Adressen speichern. Hier sehen Sie das vollständige Listing:

/* struct_arr2.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 30

static int x = 0;

struct adres {
   char vname[MAX];
   char nname[MAX];
   long PLZ;
   char ort[MAX];
   int geburtsjahr;
} adressen[100];

void Eingabe(int nr, struct adres neu[]) {
   printf("Vorname : ");
   fgets(neu[nr].vname, MAX, stdin);
   printf("Nachname : ");
   fgets(neu[nr].nname, MAX, stdin);
   printf("Postleitzahl: ");
   do {
      scanf("%5ld",&neu[nr].PLZ);
   } while(getchar()!= '\n');
   printf("Wohnort : ");
   fgets(neu[nr].ort, MAX, stdin);
   printf("Geburtsjahr : ");
   do {
      scanf("%4d",&neu[nr].geburtsjahr);
   }while(getchar()!= '\n');
}

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",search[i].vname);
         printf("Nachname.....:%s",search[i].nname);
         printf("Postleitzahl.:%ld\n",search[i].PLZ);
         printf("Ort..........:%s",search[i].ort);
         printf("Geburtsjahr..:%d\n", search[i].geburtsjahr);
         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",all[i].vname);
      printf("Nachname........:%s",all[i].nname);
      printf("Postleitzahl....:%ld\n",all[i].PLZ);
      printf("Ort.............:%s",all[i].ort);
      printf("Geburtsjahr.....:%d\n\n",all[i].geburtsjahr);

      if((!(i%2))&& i!=0) {
         printf("\n\tWeiter mit <Enter>\n\n");
         getchar();
      }
   }
}

void Sort(struct adres sort[], int nr) {
   int i,j;
   struct adres *temp;

   temp = malloc(sizeof(struct adres *));
   if(NULL == temp) {
      printf("Konnte keinen Speicher reservieren...\n");
      return;
   }
   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(void) {
   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); */
      getchar();

      switch(auswahl) {
         case 1 : Eingabe(x++,adressen);
                  break;
         case 2 : printf("Anfangsbuchstabe des Nachnamens :");
                  do {
                     scanf("%c",&c);
                  } while(getchar()!= '\n');
                  Suche(adressen,c,x);
                  break;
         case 3 : Ausgabe(adressen,x);
                  break;
         case 4 : Sort(adressen,x);
                  break;
         case 5 : printf("Ende....\n");
                  break;
         default: printf("Falsche Eingabe\n");
      }
   }while(auswahl <5);
   return EXIT_SUCCESS;
}

Der erste Funktionsaufruf des Programms lautet:

Eingabe(x++, adressen);

Damit wird die Funktion Eingabe() zur Eingabe eines Adresssatzes aufgerufen. Als Argument wird dieser Funktion die globale Variable x und die Struktur adressen vom Typ struct adres übergeben. Die globale Variable x dient als Zähler und Indexfeld und gibt an, wie viele und welche Strukturen gespeichert wurden. Der Funktionskopf sieht so aus:

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

Wenn Sie das Buch genau durchgelesen haben, wissen Sie, dass Sie auch folgende Schreibweise hätten verwenden können:

/* struct adres *neu und struct adres neu[]==call-by-reference */
void Eingabe(int nr, struct adres *neu)

Jetzt werden die ersten Daten in die Struktur eingegeben:

printf("Vorname : ");
fgets(neu[nr].vname, MAX, stdin);

fgets() liest den Vornamen des ersten Adresssatzes ein. Genauso werden auch die nächsten Daten an den einzelnen Strukturelementen übergeben. Danach können Sie einen zweiten Adresssatz eingeben.

Benötigen Sie z. B. den Nachnamen des 20. Adresssatzes (falls vorhanden), können Sie diesen wie folgt ausgeben lassen:

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

Die zweite Funktion des Programms lautet:

Suche(adressen, c, x);

Sie stellt eine primitive Suchfunktion nach dem Anfangsbuchstaben des Nachnamens dar. Die Funktion erhält als Argument die Anfangsadresse des ersten Struktur-Arrays, den Anfangsbuchstaben des Nachnamens (c) und den Indexzähler für die Anzahl der vorhandenen Strukturen (x).

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

Die Suche selbst ist relativ einfach aufgebaut:

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

In der for-Schleife wird die Anzahl der vorhandenen Adressen hochgezählt, um jeden Adresssatz mit dem eingegebenen Anfangsbuchstaben des Nachnamens zu vergleichen. Als Beispiel sei der Buchstabe »M« gegeben. Der Programmablauf sieht damit folgendermaßen aus:

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
if(search[2].nname[0] == 'M')
usw.

Diese Suchfunktion sucht nur anhand des ersten Buchstabens des Nachnamens. Bei der Suche nach ganzen Namen ist die Implementierung nicht viel komplizierter. Dazu verwenden Sie am besten die Funktion strcmp() aus der Headerdatei <string.h>. Die Funktion Ausgabe() ist die einfachste von allen. Hiermit wird lediglich der Indexzähler hochgezählt, um alle vorhandenen Adressen auf dem Bildschirm auszugeben. Als etwas schwieriger dürfte sich die Sortierfunktion erweisen:

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

So wird ein Zeiger temp vom Typ struct adres * definiert:

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

Dieser dient als temporärer Zwischenspeicher zum Austausch zweier Strukturen. Damit dieser Zwischenspeicher auch verwendet werden kann, muss Speicherplatz von der Größe der Struktur reserviert werden. Danach wird die Struktur mit dem Algorithmus Selektion Sort nach dem Anfangsbuchstaben des Nachnamens sortiert:

   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;
         }
      }
   }

Bei den Strukturen von Arrays tritt irgendwann das gleiche Problem wie bei den Arrays auf. Nach 100 Adressen ist bei diesem Programmbeispiel Schluss. Dann müssen Sie sich wieder Gedanken über neuen Speicherplatz machen. Vom Aufwand einmal abgesehen, sind Struktur-Arrays eine erhebliche Bremse für ein Programm. Nehmen wie das Sortieren als Beispiel: Alle Elemente einer Struktur müssen erst in einen temporären, extra reservierten Speicher kopiert werden. Danach müsste Speicherplatz für neue Elemente der Struktur reserviert werden. Jetzt können Sie die Daten aus dem temporären Speicher wieder zurückkopieren, und zwar in den neu angelegten Speicher für Strukturen von Arrays – von dem Fall, dass ein Element mitten in der Liste gelöscht werden soll, ganz zu schweigen. Schließlich müssen Sie diese Lücke auch wieder füllen. Somit müssten Sie z. B. alle Daten hinter dem gelöschten Element eine Position nach vorn setzen. Wenn dies bei einer Datenbank mit mehreren Tausend Adressen geschieht, wäre die Laufzeit katastrophal. Wie Sie diesen Aufwand umgehen und sich das Leben einfacher machen können, erfahren Sie in Kapitel 21, »Dynamische Datenstrukturen«.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z

 C von A bis Z
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: C/C++






 C/C++


Zum Katalog: Einstieg in C






 Einstieg in C


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de