Mit Arrays haben Sie die Möglichkeit, eine geordnete Folge von Werten, eines bestimmten Typs ab zu speichern und zu bearbeiten. Arrays werden manches mal auch als Vektoren, Felder oder Reihungen bezeichnet. C C++ C/C++ Arrays Felder Zeichenkette String Stringfunktionen Arrays - Zeichenkette String Stringfunktionen mehrdimensionale Arrays Kapitel 14: Arrays

Bisher wurden die speicherorientierten Strukturelemente auf einfache Datentypen beschränkt. Bei den Aufgaben wurden lediglich ganze Zahlen (char, short ,int, long) bzw. Fließkommazahlen (float, double, long double) besprochen. In diesem Kapitel erfahren Sie nun etwas über zusammengesetzte Datenstrukturen, kurz Arrays.

Mit Arrays haben Sie die Möglichkeit, eine geordnete Folge von Werten eines bestimmten Typs abzuspeichern und zu bearbeiten. Arrays werden auch als Vektoren, Felder oder Reihungen bezeichnet.

14.1. Arrays deklarieren            zurück  Ein Kapitel tiefer  zum Inhaltsverzeichnis

Die Syntax zur Deklaration eines Arrays sieht wie folgt aus:

Datentyp Arrayname[Anzahl_der_Elemente];

Als Datentyp geben Sie an, von welchem Datentyp die Elemente des Arrays sein sollen. Der Arrayname ist frei wählbar, mit denselben Einschränkungen für Bezeichner wie bei Variablen. Mit Anzahl_der_Elemente wird die Anzahl der Elemente angegeben, die im Array gespeichert werden können. Man spricht dabei auch vom Indexwert. Ein Array, bestehend aus Elementen unterschiedlicher Datentypen, gibt es in C nicht.

Angesprochen wird das gesamte Array mit allen Komponenten über den Arraynamen. Die einzelnen Elemente eines Arrays werden durch den Arraynamen und einen Indexwert (in eckigen Klammern) verwendet. Der Indexwert selbst wird über eine Ordinalzahl (Ganzzahl) angegeben und fängt bei Null an zu zählen.

Anhand der folgenden Zeile wird ein Array jetzt näher untersucht:

int i[5]; 

Durch diese Deklaration wird Platz für fünf Variablen im Array i vom Datentyp int im Speicher reserviert. In diesem Array können somit fünf Integerwerte gespeichert werden:

Abbildung 14.1: Anordnung eines Arrays mit fünf Werten

Abbildung 14.1: Anordnung eines Arrays mit fünf Werten



Merke
 

Die Größe eines Arrays muss zum Zeitpunkt der Übersetzung in der Regel bekannt sein. In C gibt es keine wachsenden Arrays. Natürlich gibt es auch hierzu wieder die Ausnahme von der Regel. Näheres dazu in Kapitel 15, Zeiger (Pointer).

Wie Sie in der Abbildung sehen können, wurde ein Array vom Typ int deklariert. Mit dieser Deklaration wurde automatisch auch Speicherplatz für fünf int-Werte reserviert. Bei vier Bytes für eine int-Variable (je nach System) würden 20 Bytes im Arbeitsspeicher des Rechners belegt werden. Demnach benötigt ein Array wie z.B. double a[2000] 16000 Bytes. Alte C-Compiler hatten mit großen Arrays Probleme bei der Speicherverwaltung, da der Speicher auf 64 KB beschränkt war. (Es gab natürlich Tricks, diese Schwierigkeiten zu umgehen, darauf soll hier aber nicht näher eingegangen werden.) Bei modernen 32-Bit-Compilern dürften Sie in der Praxis wohl nie an irgendwelche Grenzen stoßen.

14.2. Initialisierung und Zugriff auf Arrays            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

In dem folgenden Listing wird gezeigt, wie ein Array mit Werten initialisiert wird und wie darauf zugegriffen werden kann:

#include <stdio.h>

int main()
{
   int i[5];     /*Array mit 5 int Elementen*/
   /*Wertzuweisungen des Arrays*/
   i[0] = 5;
   i[1] = 100;
   i[2] = 66;
   i[3] = 77;
   i[4] = 1500;

   /*Ausgabe der einzelnen Array-Elemente*/
   printf("Array-Element i[0]= %d\n", i[0]);
   printf("Array-Element i[1]= %d\n", i[1]);
   printf("Array-Element i[2]= %d\n", i[2]);
   printf("Array-Element i[3]= %d\n", i[3]);
   printf("Array-Element i[4]= %d\n", i[4]);
   return 0;
}

Bei diesem Beispiel wurde an alle fünf Feldelemente ein Wert mithilfe des Indizierungsoperators [] übergeben. Und wie der Name des Operators schon sagt, dient dieser dem indizierten Zugriff auf Datentypen, die typischerweise hintereinander im Speicher abgelegt sind.

Warum lautet der Index des letzten Elements [4] und nicht [5]? Für den Computer ist die Zahl 0 auch ein Wert, und somit fängt dieser stets bei 0 an zu zählen:

Abbildung 14.2: Ein Array mit Werten initialisieren
Abbildung 14.2: Ein Array mit Werten initialisieren

Sie sehen hier 5 Zahlen: 0, 1, 2, 3 und 4. Befände sich im Programm folgende Zeile

int i[5] = 111;
printf("i[5] = %d\n",i[5]);

würde versucht, auf einen nicht reservierten Speicher zuzugreifen. Es wurde aber nur Speicher für fünf Adressen vom Datentyp int reserviert. Gefährlicher kann das werden, wenn dies in einer for-Schleife vorgenommen wird. Wird hier der Indexbereich überschritten, kann es passieren, dass mit falschen Werten weitergearbeitet wird. Hier ein Beispiel eines leider oft gemachten Fehlers:

#include <stdio.h>

int main()
{
   int test[10];
   int i;

   for(i=0; i<=10; i++)  /* !!Bereichsüberschreitung!! */
      test[i]=i;

   for(i=0; i<=10; i++)
      printf("%d, ",test[i]);
   printf("\n");
   return 0;
}

Das Programm macht nichts anderes, als das Array test[10] mit 11(!) Werten zu initialisieren, und anschließend werden diese Werte auf dem Bildschirm ausgegeben. (Haben Sie den Fehler schon gefunden?) Der Fehler liegt in der for-Schleife:

for(i=0; i<=10; i++)

Die for-Schleife wird insgesamt elf Mal durchlaufen: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10. Es kann (oder besser es wird) bei diesem Programm passieren, dass test[10] tatsächlich den Wert 10 enthält.

Sobald aber irgendwo im Programm diese Speicheradresse für eine andere Variable benötigt wird, wird der aktuelle Wert von test[10] überschrieben. Es kann also nicht garantiert werden, dass der Wert von test[10] erhalten bleibt, was zwangsläufig zu ungewollten Effekten und schwer aufzuspürenden Fehlern im Programm führt.

Wenn Sie das Programm gegenwärtig ausführen wollen, ohne dass solch ein Fehler auftritt, müssen Sie nur den Zuweisungsoperator aus den beiden for-Schleifen entfernen:

for(i=0; i<10; i++)  /* ohne '='-Zeichen richtig */

Damit wird die Schleife abgebrochen, sobald i den Wert 10 erreicht. Generell ist also Vorsicht geboten bei der Verwendung von Arrays im Zusammenhang mit Schleifen, und genau darauf zu achten, dass der Wertebereich des Feldes nicht unter- bzw. überschritten wird. Solche Unter- oder Überschreitungen werden vom Compiler nicht überprüft oder moniert.

Hinweis
 

Auf manchen Systemen gibt es eine Compiler-Option (range-checking), womit ein solcher Über- bzw. Unterlauf eines Arrays zur Laufzeit des Programms geprüft wird. Das fertige Programm sollte allerdings nicht mehr mit dieser Option übersetzt werden, da dies zu einem schlechten Laufzeitverhalten führt.

In dem Programm haben Sie gesehen, wie auf ein Array zugegriffen werden kann, um es mit Werten zu initialisieren:

for(i=0; i<10; i++)
   test[i]=i;

Statt einer konstanten Ganzzahl wurde hier die Variable i verwendet. Das funktioniert deshalb, weil diese vom Datentyp int ist und somit auch einer Ordinalzahl entspricht. Diese Variable wird von der for-Schleife bei jedem Durchlauf um den Wert eins erhöht (inkrementiert). Daraus ergibt sich, dass als Index nur Ganzzahlwerte erlaubt sind. Oftmals wird zur Bezeichnung des Index auch eine define-Konstante verwendet, wie das folgende Beispiel demonstriert:

#include <stdio.h>
#define SIZE 10

int main()
{
   int zahlen[SIZE] = { 0 };

   printf("Anz. Elemente : %d\n",sizeof(zahlen)/sizeof(int));
   return 0;
}

Solche Konstanten können die Lesbarkeit und Vermeidung von Fehlern bei längeren Programmen erheblich verbessern. Ein weiterer Vorteil entsteht, wenn Sie die Anzahl der Elemente des Arrays erhöhen wollen. Sie müssen nur den Wert der define-Konstante ändern und nicht mühsam im Programm danach suchen.

Arrays lassen sich auch anders, nämlich direkt bei der Deklaration initialisieren. Die Werte müssen dabei zwischen geschweiften Klammern stehen:

int numbers[] = {1,2,4,5,9};

Wenn Sie das Array so initialisieren, können Sie die Größe des Arrays auch weglassen. C kümmert sich darum, dass genügend Speicher zur Verfügung steht. Die einzelnen Initializer werden immer mit einem Komma getrennt und stehen in geschweiften Klammern. Dadurch ist das Feld wie folgt mit Werten belegt:

numbers[0]=1;
numbers[1]=2;
numbers[2]=4;
numbers[3]=5;
numbers[4]=9;

Natürlich können Sie trotzdem die Größe des Arrays angeben. Bei einem größeren Array hat diese Initialisierung den Vorteil, dass Sie alle anderen Werte gleich mit 0 vorbelegen können. Statt eine for-Schleife zu schreiben, wie etwa

int bigarray[1000];

for(i=0; i<1000; i++)
   bigarray[i]=0;

lässt sich das auch einfacher formulieren:

int bigarray[1000]={0};

Hier wurde nur das Array mit dem Index [0], also bigarray[0], mit dem Wert 0 initialisiert. Die restlichen 999, die nicht ausdrücklich initialisiert wurden, werden jedoch automatisch ebenfalls mit dem Wert 0 besetzt.

Dies kann aber noch ganz anders gelöst werden, und zwar unter Verwendung der folgenden Funktion:

/* Beschreibung der Funktion, siehe Abschnitt 14.14 string.h */
#include <string.h>

void *memset(void *adres, int zeichen, size_t n);

Mit der Funktion memset() wird der Wert von zeichen in jedes der ersten n Zeichen des Speicherbereichs mit der Adresse adres geschrieben. Das sieht dann wie folgt aus:

int bigarray[1000];
memset(bigarray, 0, sizeof(bigarray));

Wenn Sie das jetzt nicht nachvollziehen können: Ein paar Seiten später werden Sie es besser verstehen. Tatsächlich handelt es sich hier auch um einen Spezialfall der Verwendung von memset(), da sich dieses Verfahren nur mit dem Wert 0 auf ein int-Array anwenden lässt. Das liegt daran, dass memset() bitweise arbeitet. Bei einem int-Array auf einem 32-Bit-System würde dies bei 4 Bytes den Wert 16843009 bedeuten (alle Bits auf 1). Hier noch ein weiteres Beispiel zur Initialisierung von Arrays:

double inhalt[100] = {2.4, 2.8, 9.45, 10.99};

Hiermit wurden folgende Werte initialisiert:

inhalt [0]=2.4
inhalt [1]=2.8
inhalt [2]=9.45
inhalt [3]=10.99
inhalt [4]=0.0
inhalt [5]=0.0
inhalt [6]=0.0
…
inhalt[997]=0.0
inhalt[998]=0.0
inhalt[999]=0.0

Ab inhalt[4] bis inhalt[999] werden alle Werte automatisch mit 0.0 initialisiert. Leider ist es nicht möglich, den Inhalt eines Arrays mit einem anderen konstanten Wert außer 0 zu initialisieren.

Hinweis
 

Manche Systeme vertragen keine lokalen, übergroß dimensionierten Arrrays. Sollte das Programm bei Ihnen gleich nach dem Start abstürzen, und Sie verwenden ein recht großes Array, dann könnte ein global definiertes Array Abhilfe schaffen.

14.2.1 Gültigkeitsbereich von Arrays
Der Gültigkeitsbereich von Arrays richtet sich danach, ob es sich dabei um ein statisches, globales oder ein normales (lokales) Array handelt. Betrachten Sie zur Verdeutlichung ein kleines Beispielprogramm:

#include <stdio.h>

int wert_global[5];

int main()
{
   static int wert_static[5];
   int wert_auto[5];
   int i;
   for(i=0; i<5; i++)
      printf("%d:\t%10d\t%10d\t%10d\n"
                  ,i,wert_global[i],wert_static[i],wert_auto[i]);
   return 0;
}

Die Ausgabe des Programms am Bildschirm sieht wie folgt aus:

Abbildung 14.3: Gültigkeitsbereich von Variablen
Abbildung 14.3: Gültigkeitsbereich von Variablen

Das Programm gibt für das globale und für das mit dem Schlüsselwort static deklarierte Array jeweils den Wert 0 aus. Das automatische Array wert_auto hingegen gibt einen undefinierten Wert zurück. Daraus lässt sich schließen, dass globale und mit static deklarierte Arrays automatisch mit 0 initialisiert werden.

Das Verhalten des Programms ändert sich, wenn die Automatic-Variable (wert_auto) mit mindestens einem Wert initialisiert wird:

#include <stdio.h>

int wert_global[5];

int main()
{
   static int wert_static[5];
   int wert_auto[5] = { 0 };  /* Array mit 0 initialisiert */
   int i;
   for(i=0; i<5; i++)
      printf("%d:\t%10d\t%10d\t%10d\n",
                   i,wert_global[i],wert_static[i],wert_auto[i]);
  return 0;
}

Es wurde hier nur die Zeile

int wert_auto[5] = {0};

verändert und wert_auto[0] mit dem Wert 0 initialisiert. Die Ausgabe des Programms zeigt jetzt (erwartungsgemäß) die initialisierten Werte.

Abbildung 14.4: Gültigkeitsbereich von Variablen
Abbildung 14.4: Gültigkeitsbereich von Variablen

14.3. Arrays vergleichen            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Mithilfe des Indizierungsoperators [] können Sie zwei int-Arrays auf Gleichheit überprüfen:

#include <stdio.h>

int main()
{
   int i;
   int array1[10];
   int array2[10];

   for(i=0; i<10; i++)
      {
         array1[i]=i;
         array2[i]=i;
      }
   array2[5] = 100; /* array2 an Pos. 5 verändern */

   for(i=0; i<10; i++)
      {
         if( array1[i] == array2[i] )
            continue;
         else
            {
               printf("Unterschied an Position %d\n",i);
               break;
            }
      }
   return 0;
}

Mit der Zeile

if( array1[i] == array2[i] )

werden die einzelnen Werte array1[i] und array2[i] miteinander verglichen. Es werden also alle Elemente der Arrays durchlaufen und verglichen. Folgendes funktioniert allerdings nicht:

if( array1 == array2 )

Ganze Arrays lassen sich nicht miteinander vergleichen. In diesem Fall wurden lediglich zwei Speicheradressen verglichen. Für den Vergleich vollständiger bzw. kompletter Arrays gibt es folgende Funktion:

#include <string.h>

int memcmp(const void *adr1, const void *adr2, size_t n);

Diese Funktion vergleicht n Zeichen aus Adresse adr1 und Adresse adr2. Sind beide Speicherbereiche gleich, liefert die Funktion den Wert 0 zurück (weitere Beschreibung zu dieser Funktion siehe Abschnitt 14.14). Hierzu ein Beispiel mit der Funktion memcmp():

#include <stdio.h>
#include <string.h>

int main()
{
   int i;
   int array1[10];
   int array2[10];

   for(i=0; i<10; i++)
      {
         array1[i]=i;
         array2[i]=i;
      }
   array2[5] = 100; /* Verändert array2 an Pos. 5 */

   if(memcmp(array1, array2, sizeof(array1)) == 0 )
      printf("Beide Arrays haben den gleichen Inhalt\n");
   else
      printf("Die Arrays sind unterschiedlich\n");
   return 0;
}

14.4. Anzahl der Elemente eines Arrays (ermitteln)            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Wie lässt sich die Anzahl der Elemente eines Arrays ermitteln? Dies kann mit dem sizeof-Operator realisiert werden, den Sie bereits kennen gelernt haben. Mit ihm lässt sich die Größe eines Datentyps in Byte ermitteln. Folgendes Array soll als Beispiel dienen:

int zahlen[] = { 3,6,3,5,6,3,8,9,4,2,7,8,9,1,2,4,5 };

Jetzt soll der sizeof-Operator auf dieses Array angewendet werden:

#include <stdio.h>

int main()
{
   int zahlen[] = {3,6,3,5,6,3,8,9,4,2,7,8,9,1,2,4,5};

   printf("Anzahl der Elemente: %d\n",sizeof(zahlen));
   return 0;
}

Bei der Ausführung des Programms erhalten Sie auf einem 16-Bit-System als Ergebnis den Wert 34 und auf einem 32-Bit-System den Wert 68. Dass dieser Wert nicht der Anzahl der Elemente entspricht, ist leicht nachvollziehbar. Der Wert 34 bzw. 68 stellt in diesem Beispiel zunächst nur die Größe des Arrays in Byte dar. Damit die Anzahl der Elemente bestimmt werden kann, muss dieser Wert durch die Größe des Array-Datentyps geteilt werden:

#include <stdio.h>

int main()
{
   int zahlen[] = {3,6,3,5,6,3,8,9,4,2,7,8,9,1,2,4,5};

   printf("Anz. Elemente : %d\n",sizeof(zahlen)/sizeof(int));
   return 0;
}

Damit haben Sie die richtige Anzahl der Elemente (17) ermittelt.

14.5. Übergabe von Arrays an Funktionen            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Um Arrays an Funktionen zu übergeben, geht man ähnlich vor wie bei Variablen. Die Funktionsdeklaration sieht folgendermaßen aus:

void function(int feld[], int n_Anzahl) 

Auffällig ist hier, dass der Indexwert für die Größe des Arrays nicht angegeben wird. Das liegt daran, dass der Funktion nicht bekannt ist, wie viele Elemente das Array besitzt. Daher ist es empfehlenswert, der Funktion die Anzahl der Elemente als Argument mitzugeben, wie auch im Beispiel oben bei der Deklaration der Variable n_Anzahl zu sehen ist.

Hierbei kommen Sie zum ersten Mal mit Zeigern in Berührung. Arrays werden bei einer Funktion nicht wie Variablen (call-by-value) kopiert, sondern als Zeiger übergeben (call-by-reference, siehe Kapitel 15, Zeiger). Somit muss die Funktion nicht notwendigerweise eine Kopie für das übergebene Array anlegen (wie sonst üblich), sondern arbeitet lediglich mit der (Anfangs-) Adresse des Arrays. Es ist also nicht zwingend erforderlich, die Größe des Arrays als Parameter an eine Funktion zu übergeben, da auf diese Weise von der Anfangsadresse eines Arrays aus sequenziell alle Elemente des Arrays erreicht werden können. Dieser enge Zusammenhang zwischen Arrays und Pointern wird in Kapitel 15 ausführlich erklärt.

Aufgerufen wird die Funktion mit folgenden Argumenten:

#define MAX 100
…
function(feld, MAX);

Damit bekommt die Funktion function() die Anfangsadresse des Arrays feld übergeben. Es wäre auch folgender Funktionsaufruf möglich:

function(&feld[0], MAX); 

Auch hier wird der Funktion die Anfangsadresse, also die Adresse des ersten Elements des Arrays übergeben. Jetzt ist Ihnen zwar bekannt, dass ein Array an eine Funktion als Referenz (auf eine Adresse) übergeben wird. Wie aber ist vorzugehen, wenn ein Array unbedingt als Kopie übergeben werden soll? Sie können das Array in eine Struktur verpacken und dann an die Funktion übergeben. Näheres zu den Strukturen erfahren Sie weiter unten. Für den Fall der Fälle, hier das Beispiel dazu:

#include <stdio.h>

struct array{ int wert[3]; };

void output_array(struct array z)
{
   int i;
   for(i=0; i < sizeof(struct array)/sizeof(int); i++)
      printf("%d\t",z.wert[i]);
   printf("\n");
}

int main()
{
   struct array new_array;
   new_array.wert[0] = 10;
   new_array.wert[1] = 20;
   new_array.wert[2] = 30;

   /* call-by-value */
   output_array(new_array);
   return 0;
}

14.6. Arrays aus Funktionen zurückgeben            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Arrays können nicht als Rückgabetyp von Funktionen definiert werden. Auch dazu wird sich des bekannten Tricks bedient, Arrays in eine Struktur zu verpacken. Auch hierzu ein Listing zur Demonstration:

#include <stdio.h>

struct array{ int wert[3]; };

struct array init_array()
{
   int i;
   struct array z;
   for(i=0; i < sizeof(struct array)/sizeof(int); i++)
      {
         printf("Wert %d eingeben: ",i);
         scanf("%d",&z.wert[i]);
      }
   return z;
}

void output_array(struct array z)
{
   int i;
   for(i=0; i < sizeof(struct array)/sizeof(int); i++)
      printf("%d\t",z.wert[i]);
   printf("\n");
}

int main()
{
   struct array new_array;
   /* Array als Rückgabewert in einer Struktur verschachtelt */
   new_array=init_array();
   /* call-by-value */
   output_array(new_array);
   return 0;
}

Die letzten beiden Listings dürften einen Programmierneuling ein wenig verwirrt haben, da zur Demonstration Strukturen verwendet wurden, die erst in einem späteren Kapitel zur Sprache kommen. Blättern Sie an späterer Stelle gegebenenfalls hierher zurück.

14.7. Programmbeispiel zu den Arrays            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Das folgende, etwas umfangreichere Beispiel zeigt, welche Möglichkeiten der Verwendung Arrays bieten. Das Beispielprogramm wertet eine Statistik für zwei Fußballmannschaften aus, und zwar das Tore- und Punkteverhältnis der letzten fünf Spiele, die beide Mannschaften gegeneinander gespielt haben:

#include <stdio.h>
/*Bilanz aus 5 Spielen*/
#define SPIELE 5
#define WIN    3
#define LOSE   0
#define REMIS  1

/* Alle Elemente mit 0 initialisieren */
int Bayern[SPIELE]  = {0};
int Borussia[SPIELE]= {0};

/*Funktion zum Zaehlen der Punkte*/
void punkte(int bm[], int bd[], int count)
{
   if(bm[count] > bd[count])
      {
         bm[count]=WIN;  /*3 Punkte für Bayern*/
         bd[count]=LOSE;
      }
   else if(bm[count] < bd[count])
      {
         bm[count]=LOSE;
         bd[count]=WIN;  /*3 Punkte für Borussia*/
      }
   else if(bm[count] == bd[count])
      {
         bm[count]=REMIS; /* 1Punkt für jeden - Unentschieden*/
         bd[count]=REMIS;
      }
}

/* Hauptprogramm */
int main()
{
   unsigned int tor1,tor2;
   unsigned int tmptor1=0,tmptor2=0;
   unsigned int punkte_bay=0, punkte_bor=0;
   unsigned int count=0;        /*Indexzaehler*/

/* Eingabe des Anwenders */
   printf("Eingabe der letzten %d Spiele\n", SPIELE);

   while(count != SPIELE)
      {
         printf("%d. Spiel : Bayern - Borrusia\n",count+1);
         printf("Tor(e) Bayern   : ");
         scanf("%2d",&tor1);
         Bayern[count]=tor1;
         printf("Tor(e) Borussia : ");
         scanf("%2d",&tor2);
         Borussia[count]=tor2;

         tmptor1+=tor1;         /*Tore zaehlen Bayern*/
         tmptor2+=tor2;         /*Tore zaehlen Borussia*/
         /*Werte an Funktion punkte() uebergeben*/
         punkte(Bayern,Borussia,count);

         /* Punkte zaehlen */
         punkte_bay+=Bayern[count];
         punkte_bor+=Borussia[count];
         /* Nächstes Spiel */
         count++;
      }
   /* Ausgabe der Statistik */
   printf("\n\nStatistik der letzten %d Spiele\n\n",SPIELE);
   printf("Bayern - Borussia\n");
   printf("Punkte : %2d : %2d\n",punkte_bay,punkte_bor);
   printf("Tore   : %2d : %2d\n",tmptor1,tmptor2);

   return 0;
}

Die Bildschirmausgabe des Programms könnte (abhängig von den Eingabewerten) z.B. so aussehen:

Abbildung 14.5: Ausgabe des Programmbeispiels
Abbildung 14.5: Ausgabe des Programmbeispiels

Das Programm, Schritt für Schritt erläutert:

int Bayern[SPIELE]  = {0};
int Borussia[SPIELE]= {0};

Hier wird jeweils ein Array mit dem Wert 0 initialisiert. Sehr wichtig im Programm ist die Variable

unsigned int count=0;

Mit dieser wird die Anzahl der gespielten Spiele gezählt.

In der while-Schleife der Hauptfunktion werden Sie aufgefordert, das Endergebnis jedes einzelnen Spiels einzugeben. Der Wert wird an die Arrays mittels

Bayern[count]=tor1;
…
Borussia[count]=tor2;

übergeben. War das erste Ergebnis beispielsweise 2:1 für Bayern, dann bekommen die Elemente mit dem Index 0 folgende Werte:

Bayern[0]=2;
…
Borussia[0]=1;

Diese beiden Werte werden danach mit der Anzahl absolvierter Spiele an die Funktion void punkte(…) übergeben:

punkte(Bayern, Borussia, count);

Tatsächlich werden hier die Anfangsadressen der Arrays an die Funktion punkte() übergeben. Dort wird mit if-else-Anweisungen überprüft, welcher der beiden Werte höher ist. Dabei ist das aktuelle Ergebnis von Interesse, welches mit dem Index [count] angegeben ist. Im konkreten Beispiel (2:1) wäre folgende Bedingung wahr:

if(bm[count] > bd[count])
   {
      bm[count]=WIN;   /* 3 Punkte für Bayern */
      bd[count]=LOSE;
   }

Somit werden den Elementen der Arrays folgende Werte zugewiesen:

bm[0]=3    /* Punkte für Bayern */
bd[0]=0    /* Punkte für Borussia */

Wenn Borussia siegen sollte, überprüft die Funktion punkte() die nächste Bedingung. Die letzte else-if-Anweisung steht für ein Unentschieden beider Mannschaften, und jeder bekommt einen Punkt. Danach fährt das Programm fort mit der while-Schleife der Hauptfunktion. Dort wird mit

count++;

der Indexzähler um 1 erhöht, und es kommt die nächste Abfrage der Werte für:

Bayern[1]=… und Borussia[1]=… 

Es werden so lange Werte eingegeben, bis

while(count != SPIELE) 

unwahrheitsgemäß abbricht. Das ist der Fall, sobald count == SPIELE wird, also 5 Spiele gespielt wurden. Anschließend wird die Gesamtpunktzahl von jedem Team auf dem Bildschirm ausgegeben. Zur Vergabe von Punkten wurden hier symbolische Konstanten verwendet, falls sich im Reglement wieder einmal etwas in der Punktevergabe ändert.

14.8. Einlesen von Array-Werten            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Einlesen können Sie die vom Benutzer eingegebenen Werte für ein Array beispielsweise mit scanf(), z.B. folgendermaßen:

#include <stdio.h>
#define MAX 5

int main()
{
   int i;
   int array[MAX];

   for(i=0; i<MAX; i++)
      {
         printf("%d. Zahl > ",i+1);
         scanf("%d",&array[i]);
      }
   printf("Sie haben eingegeben: ");

   for(i=0; i<MAX; i++)
      printf("%d ",array[i]);
   printf("\n");
   return 0;
}

Sie müssen lediglich das Indexfeld mithilfe des Indizierungsoperators verwenden, das Sie mit einem Wert versehen wollen.

14.9. Mehrdimensionale Arrays            zurück  Ein Kapitel höher  zum Inhaltsverzeichnis

Arrays, wie sie bisher besprochen wurden, können Sie sich als einen Strang von hintereinander aufgereihten Zahlen vorstellen. Man spricht dann von eindimensionalen Arrays oder Feldern. Es ist aber auch möglich, Arrays mit mehr als nur einer Dimension zu verwenden:

int Matrix[5][4];    /* Zweidimensional */ 

Hier wurde z.B. ein zweidimensionales Array mit dem Namen Matrix definiert. Dies entspricht im Prinzip einem Array, dessen Elemente wieder Arrays sind. Sie können sich dieses Feld wie bei einer Tabellenkalkulation vorstellen:

Abbildung 14.6: Ein zweidimensionales Array (5 x 4)

Abbildung 14.6: Ein zweidimensionales Array (5 x 4)

Weiter mit 14.10. Mehrdimensionale Arrays initialisieren            zum Inhaltsverzeichnis