Felder

Ein Feld (engl. Array) ist die Zusammenfassung mehrere Elemente desselben Typs in einer Variablen. Sehen wir uns als Erklärung das Programmierbeispiel genauer an:

    // Zwei Ganzzahlen hintereinander im Speicher anlegen
    int a[2];

    // Array-Indizierung findet ab Null statt (!)
    a[0] = 1;
    a[1] = 2;

    // Array-Elemente ausgeben
    cout << "a: " << a[0] << " | " << a[1] << endl;

Durch die Deklaration legen wir gleich zwei Integer hintereinander im Speicher an. Auf die einzelnen Werte der Integer können wir nachher durch Indizes in eckigen Klammern zugreifen. Sowohl a[0] als auch a[1] können wir als durchnummerierte Variablen vom Typ Integer betrachten.

Dass wir auf das erste Element unseres Arrays durch a[0] zugreifen, ist wohl für die meisten etwas gewöhnungsbedürftig. C++ ist sehr Hardwarenah, und mit Null anzufangen hat Geschwindigkeitsvorteile auf allen gängigen Prozessoren. Dazu später mehr.

Arrays lassen sich, wie Variablen, bei der Deklaration initialisieren. Dazu verwendet man eine Notation aus geschweiften Klammern und durch Kommata getrennten Elementen.

    // Initialisierung mit Wert bei Deklaration
    int b[2] = { 1, 2 };

Warum aber haben wir genau zwei Variablen verwendet? Und woher sollen wir nachher wissen, wie weit wir in einer for-Schleife zählen können, um die durchnummerierten Elemente zu verändern? Besser geht es deshalb so:

    // Besser: Arraygröße in Konstante definieren,
    // damit sie nachher verwendet werden kann
    const unsigned int N = 4;
    int c[N];

    // Auch Ganzzahl-Variablen können als
    // Index verwendet werden... Vorsicht:
    // Array hat N Elemente - Indizes gehen
    // daher von 0 bis N-1
    for (unsigned int i = 0; i < N; i++)
    {
        c[i] = int(i);
    }

In der for-Schleife ist zu erkennen, dass wir auf i < N abprüfen, nicht auf i <= N, damit i zwischen 0 und N-1 bleibt. C++ prüft die Indizes nicht, während das Programm läuft. Wenn ihr über die Grenzen eines Arrays hinaus Daten lest oder schreibt, erhaltet ihr unter Umständen Fehler und Abstürze, unter Umständen aber auch nicht... Achtet unter allen Umständen auf die korrekten Grenzen der Arrays!

Der Lohn für diese mögliche Fehlerquelle ist Geschwindigkeit im Vergleich zu anderen Programmiersprachen. Leider gibt es in C++ nicht die Möglichkeit, ohne Umwege Arrays mit dynamischer, also wechselnder, Größe anzulegen. Die Größe einfacher Arrays ist, wie im Beispiel, immer fest.

Zweidimensionale Felder

Zu etwas Erfreulicherem. Mit Arrays lassen sich auch mehrdimensionale Felder anlegen. In unserem Beispiel erzeugt und initialisiert

    // Zweidimensionale arrays (hardcoded)
    int d[2][2] = { { 1, 2 },
                    { 3, 4 } };

ein zweidimensionales (2x2) Feld mit vier Werten. Die geschwungenen Klammern und Kommata sind jetzt ineinander verschachtelt. Genau genommen deklarieren und initialisieren wir genau zwei Variablen vom "Typ" int[2].

Durch eine Notation mit doppelten eckigen Klammern kann danach auf die Elemente unseres Feldes zugegriffen werden:

    cout << "d: " << d[0][0] << " | " << d[0][1] << endl;
    cout << "   " << d[1][0] << " | " << d[1][1] << endl;

Jetzt laufen eben zwei Indizes von 0 bis jeweils (2-1). Bleiben wir bei der Erklärung, dass wir eigentlich zwei Deklarationen ineinander verschachtelt haben. Der Zugriff auf die Elemente ist durch zwei ineinander verschachtelte for-Schleifen möglich. Genau das tun wir am Ende des Beispiels:

    // Zweidimensionale arrays (besser)
    const unsigned int M = 2;
    int e[M][N];
    for (unsigned int j = 0; j < M; j++)
    {
        for (unsigned int i = 0; i < N; i++)
        {
            e[j][i] = int(j)*int(N) + int(i);
        }
    }

Dass wir außen j und innen i druchzählen, ist damit begründet, wie C++ die Daten im Speicher ablegt. Wir könnten es auch anders herum programmieren, was allerdings Geschwindigkeitsnachteile hätte. Als Faustregel gilt: Das letzte Element in eckigen Klammern sollte in der innersten Schleife durchgezählt werden, die weiter vorne liegenden Elemente dann in der entsprechenden Reihenfolge weiter außen.

Selbständige Programmierung
  • Deklariere ein dreidimensionales Array aus floats, initialisiere es und gebe dessen Werte aus.

zurück