Eindimensionale Arrays und Funktionen

Ein Array ist eine Kombination mehrerer Variablen gleichen Typs. Die Elemente des Arrays werden über ihre Positionsnummer angesprochen.

Der Begriff Array wird in der deutschen Fachliteratur oft mit dem Wort Feld„ übersetzt. Leider ist dieser Begriff nicht sehr markant, so dass viele Programmierer den Begriff „Array“ bevorzugen. Zu diesen gehöre ich auch, und darum halte ich es auch hier so.

Realitätsabbildung

Sie können mit einem Array also eine Reihe gleicher Elemente ansprechen. Ein Beispiel sind die Lottozahlen. Es werden immer sechs ganze Zahlen gezogen. Wenn Sie also die Lottozahlenziehung in einem Programm simulieren wollen, bietet es sich an, ein Array von sechs Integern zu verwenden.

In der Abbildung sehen Sie wie die Lottozahlen nebeneinander stehen. Unter jedem Kasten befindet sich in eckigen Klammern die Position jeder Lottozahl. Entgegen der Gewohnheit der meisten Menschen beginnt ein Array immer an der Position 0. Wenn also sechs Zahlen im Array stehen, befindet sich die letzte an Position 5.

Definition

Um das Array für die Lottozahlen im Programm zu definieren, geben Sie zunächst den Typ eines einzelnen Elements an. Als nächstes kommt der Name des Arrays. Es folgt in eckigen Klammern die Anzahl der Elemente, die das Array maximal aufnehmen können soll.

int Lotto[6];

Zugriff

Wenn Sie auf ein Element des Arrays zugreifen wollen, nennen Sie zuerst den Namen des Arrays. Es folgt in eckigen Klammern die Position des Elements, auf das Sie zugreifen wollen. Denken Sie dabei daran, dass die Array-Positionen immer bei 0 beginnen.

lotto[2] = srand() % 49 + 1;
cout << lotto[0];

Die erste Zeile zeigt, wie das dritte Element – nicht das zweite – mit einer Zufallszahl zwischen 1 und 49 gefüllt wird. Die zweite Zeile gibt das erste Element auf dem Bildschirm aus.

Eckige Klammern

Das syntaktische Erkennungszeichen eines Arrays sind die eckigen Klammern. Sie werden bei der Definition eines Arrays verwendet, um anzugeben, wie viele Variablen zu dem Array gehören. Die eckigen Klammern werden auch verwendet, wenn auf ein Element zugegriffen werden soll. Darum werden die eckigen Klammern Indexoperator genannt. Das Beispiel zeigt, wie das Lottozahlen-Array mit Zufallszahlen gefüllt wird:

int lotto[6];
srand(0);
for(i=0; i<6; i++)
{
    lotto[i] = rand() % 49 + 1;
}

Index

Die Variable lotto ist ein Array für den Typ Integer. Die eckigen Klammern mit der 6 in der Mitte sagen aus, dass hier sechs Integer-Variablen definiert sind. Wie man auf diese sechs Werte zugreift, sehen Sie in der for-Schleife. Dort wird den sechs Variablen nacheinander eine Zufallszahl zwischen 1 und 49 zugewiesen. Welche der sechs Variablen verwendet wird, steht in den eckigen Klammern. Die Positionsnummer nennt man auch Index. Der Index beginnt bei C + + immer bei 0. Da es sechs Elemente gibt, läuft der Index von 0 bis 5.

Da die Elemente zufällig bestückt wurden, ist es möglich, dass zwei der Elemente gleich sind. Im nächsten Schritt wird bei Gleichheit zweier Zahlen neu gezogen. Sie können in einer Schleife alle bisherigen Zahlen durchlaufen und prüfen, ob die neue Zahl bereits gezogen wurde. Das folgende Programm garantiert, dass die gezogenen Lottozahlen nicht doppelt auftreten:

#include <iostream>
#include <stdlib.h>
using namespace std;
 
int main()
{
    int lotto[6];
    int i, j;
    bool neueZahl;
 
    srand(0);
    for(i=0; i<6; i++) // ziehe nacheinander sechs Zahlen
    {
        do  // wiederhole die Ziehung, bis die neue Zahl
        {   // nicht mit einer der vorigen identisch ist.
            lotto[i] = rand() % 49 + 1;
            neueZahl = true; // positive Grundeinstellung
            for (j=0; j<i; j++)
            {  // durchlaufe alle bisher gezogenen Kugeln
                if (lotto[j]==lotto[i])
                { // Hier wurde ein Doppelter entdeckt
                    neueZahl = false;
                }
            }
        } while (!neueZahl);
    }
    for (i=0; i<6; i++)
    {
        cout << lotto[i] << " ";
    }
    cout << endl;
}

Die äußere Schleife mit der Variablen i als Index durchläuft die Anzahl der zu ziehenden Lottozahlen. Die Ziehung selbst erfolgt innerhalb der do-while-Schleife, denn sie soll so lange wiederholt werden, bis man eine Zahl findet, die bisher noch nicht gezogen wurde. Die Entscheidung kann also erst nach der Aktion im Schleifenkörper gefällt werden. Damit ist eine fußgesteuerte Schleife die Idealbesetzung. Nach der Ziehung erfolgt die Prüfung. In einer inneren for-Schleife werden alle bisher gezogenen Zahlen durchlaufen. Das bedeutet, der Index j startet bei 0 und bleibt kleiner als i, d. h. kleiner als der Index für die aktuell gezogene Zahl. Im Falle einer Gleichheit mit den bisher gezogenen Zahlen wird die boolesche Variable neueZahl auf false gesetzt. Das führt zu einer Wiederholung der Ziehung. Nach jeder Ziehung muss diese Variable auf true gesetzt werden, sonst wird die Schleife nie verlassen, sobald einmal eine Doppelziehung entdeckt wurde. Index und Größe Wie schon erwähnt, beginnt jedes Array mit dem Index 0. Das ist für den allgemeinen Sprachgebrauch oft irritierend, da das erste Element nicht den Index 1, sondern den Index 0 hat. Ein Array mit sechs Elementen hat 5 als höchsten Index. Um die Verwirrung komplett zu machen: Bei der Deklaration wird bei einem Array mit sechs Elementen wiederum eine 6 zwischen die rechteckigen Klammern geschrieben. Beim Zugriff darf zwischen den eckigen Klammern aber maximal eine 5 stehen. Diese Zusammenhänge sollten Ihnen in Fleisch und Blut übergehen.

int lotto[6];
lotto[0] = 1; // erstes Element!
...
lotto[5] = 3; // sechstes Element, ok!
lotto[6] = 4; // Das siebte Element: Fehler!!!

Beispiel: Ermittlung von n Quicktipps im Lotto 6 aus 45 Wir beginnen mit einer Version ohne und Funktionen und bauen diese dann entsprechend um!

void main()
{
  int n;	//Anzahl der Tipps
  int tipp[6];
  srand(time(0));
  cout<<"Wie viele Tipps moechten Sie erhalten?";
  cin>>n;
  for(int i=1;i<=n;i++){ 	//n Tipps ermitteln
	cout<<"\n"<<i<<". Tipp: ";
 
	for(int j=0; j<6;j++){
		tipp[j]=rand()%45+1;
		cout<<tipp[j]<<" ";
	}
  }
  getch();
}

Bei der Verwendung von Arrays in Funktionen sind einige Besonderheiten zu beachten:

Wir erweitern nun das obige Beispiel um den Einsatz von Funktionen:

void erzeugeQuicktipp(int a[6]);
 
void main()
{
  int n;	//Anzahl der Tipps
  int tipp[6];
  srand(time(0));
  cout<<"Wie viele Tipps moechten Sie erhalten?";
  cin>>n;
  for(int i=1;i<=n;i++){ 	//n Tipps ermitteln
	cout<<"\n"<<i<<". Tipp: ";
	erzeugeQuicktipp(tipp);
  }
  getch();
}
 
void erzeugeQuicktipp(int a[6]){
  for (int i=0; i<6; i++) {
	  a[i]=rand()%45+1;
	  cout<<a[i]<<" ";
  }
}

Erweitere das Beispiel nun um eine eingene Funktion für die Ausgabe. Außerdem soll verhindert werden, dass innerhalb eines Tipps Zahlen doppelt vorkommen.

    // Programm: lotto.cpp
    // Beschreibung: Erzeugen von Lotto-Tips
    #include <iostream>      // Zusatzbibliothek für Ein-und Ausgaben wird eingebunden
    #include <conio.h>       // Zusatzbibliothek für Konsole wird eingebunden
    #include <stdlib.h>      // Wird für Zufallszahl-Generator benötigt
    #include <time.h>        // Wird für Initialisierung des Zufallszahl-Generator benötigt
    using namespace std;     // Standard-Namensraum wird eingestellt
 
    void erzeugeQuicktipp(int a[6]);
    void ausgabe(int a[6]);
 
    int main(){
      int n;	//Anzahl der Tipps
      int tipp[6];
      srand(time(0));
      cout<<"Wie viele Tipps moechten Sie erhalten?"; cin>>n;
      for(int i=1;i<=n;i++){ 	//n Tipps ermitteln
	    cout<<"\n"<<i<<". Tipp: ";
	    erzeugeQuicktipp(tipp);
	    ausgabe(tipp);
      }
      getch();
      return 0;	
    }
 
    void erzeugeQuicktipp(int a[6]){
      for (int i=0; i<6; i++) {
	    a[i]=rand()%45+1;
	    //Überprüfe, ob Zahl bereits vorhanden
	    for(int j=0;j<i;j++){   //Durchlaufe die vorhandenen Einträge
		   if(a[i]==a[j]){  //und überprüfe sie auf Gleichheit mit dem aktuellen Eintrag
			i--;        //ist die Zahl bereits vorhanden, so setze
				    //Zähler i zurück, damit diese Zufallszahl
			            //automatisch nochmals erzeugt wird!
		   }
	    } 
      }
    }     
 
    void ausgabe(int a[6]){
	  for (int i=0; i<6; i++) {
	 	cout<<a[i]<<" ";
  	  }  
    }