Teil 1: Grundlagen


Felder und C-Strings

Felder

Feld-Definition

Um mehrere zusammengehörige Daten eines Datentyps abzuspeichern, werden Felder (Arrays) eingesetzt. Ein Feld wird wie folgt definiert:

DTYP name[SIZE];

DTYP definiert den Datentyp der im Feld abzulegenden Daten und name ist der Name des Feldes. Danach folgt innerhalb eckiger Klammern die Feldgröße SIZE. Sie definiert die maximale Anzahl der Daten, die im Feld abgelegt werden können. SIZE muss eine ganzzahlige Konstante sein.

Außer eindimensionalen Felder können auch mehrdimensionale Felder definiert werden. Dabei werden die einzelnen Dimensionen unmittelbar hintereinander jeweils in einer eckigen Klammer aufgeführt. So definiert short array[2][3]; ein Feld mit der Dimension 2x3.

Felder können bei ihrer Definition gleich mit Daten belegt werden. Dabei folgt nach der eckigen Klammer eine paar geschweifte Klammern und innerhalb dieser werden die Daten, durch Komma getrennt, aufgelistet. Soll das Feld genauso groß dimensioniert werden, dass die aufgelisteten Daten abgelegt werden können, kann die Angabe der Feldgröße entfallen. In diesem Fall ist eine leere eckige Klammer anzugeben. Wie Sie dann die tatsächliche Feldgröße ermitteln, z.B. um die Feldelemente in einer for-Schleife auszugeben, sehen Sie gleich in einem Beispiel.

Zugriff auf Feldelemente

Um auf ein Feldelement zuzugreifen, wird zuerst der Feldname angegeben, gefolgt von einem eckigen Klammerpaar. Innerhalb des Klammerpaars steht dann der Index des Feldelements, wobei das erste Element den Index 0 besitzt und das letzte Element demzufolge den Index SIZE-1. Bei mehrdimensionalen Feldern werden entsprechend viele Indizes hintereinander angegeben.

#include <iostream>
using std::cout;
using std::endl;

int main()
{
    // 1-dimensionales Feld anlegen mit expliziter Feldgroesse
    const int SIZE1 = 10;  // Feldgroesse
    short sArray[SIZE1];   // Feld definieren

    // Feld mit Daten fuellen
    for (auto index = 0; index < SIZE1; index++)
        sArray[index] = index * 2;
    // Feldinhalt ausgeben
    for (auto index = 0; index < SIZE1; index++)
        cout << sArray[index] << ',';
    cout << endl;

    // 1-dimensionales Feld mit impliziter Feldgroesse
    short siArray[]{ 10,20,30 };   // Feld definieren und initialiseren
    // Feldgroesse von siArray berechnen
    // Groesse = Groesse des Feldes / Groesse eines Elements
    const int SIZE2 = sizeof(siArray) / sizeof(siArray[0]);
    // Feldinhalt ausgeben
    for (auto index = 0; index < SIZE2; index++)
         cout << siArray[index] << ',';
    cout << endl;

    // 2-dimensionales Feld definieren und initialisieren
    const int XSIZE = 2, YSIZE = 3;
    int iFeld[XSIZE][YSIZE]{ {1,2,3}, {10,20,30} };
    // Auch dieses Feld ausgeben
    for (auto xindex = 0; xindex < XSIZE; xindex++)
    {
        for (auto yindex = 0; yindex < YSIZE; yindex++)
            cout << iFeld[xindex][yindex] << ','; cout << endl;
    }
}

Alternativ kann der Zugriff auf Feldelemente in einem eindimensionalen Feld auch mittels eines Zeigers erfolgen. Der Zeiger muss dann den gleichen Datentyp wie das Feld besitzen. Um in einem Zeiger die Adresse eines Feldelements abzulegen, wird rechts vom Zuweisungsoperator der Adressoperator gefolgt vom Feldelement angegeben, z.B. ptr = &array[3];. Eine Sonderstellung nimmt dabei der Verweis auf den Beginn eines eindimensionalen Feldes ein. In diesem Fall genügt die alleinige Angabe des Feldnamens (ptr = array;).

#include <iostream>
using std::cout;
using std::endl;

int main()
{
    // Eindimensionales Feld definieren/initialisieren
    short array[]{ 10,20,30 };
    // Anzahl der Elemente im Feld
    const int SIZE = sizeof(array) / sizeof(array[0]);
    // Feldinhalt über Zeiger ausgeben
    for (short* pArray = array; pArray != &array[SIZE]; pArray++)
        cout << *pArray << ',';
    cout << endl;
}

Der Zugriff auf mehrdimensionale Felder mittels Zeiger ist etwas komplizierter (Zeiger auf Feld mit Zeigern!) und soll an dieser Stelle nicht weiter betrachtet werden. Mehr dazu erfahren Sie im Internet unter ' c++ pointer multidimensional array' oder in meinem Buch.

C-Strings und Felder

Für C-Strings wurden bisher immer Literale verwendet, die in Anführungszeichen eingeschlossen sind. Ein solcher C-String kann auch in einem Feld abgelegt werden. Da C-Strings in der Regel aus 1 Byte großen ASCII-Zeichen bestehen, sind sie in einem char-Feld abzulegen.

Bei der Definition eines char-Feldes kann das Feld mit einem C-String initialisiert werden, so wie nachfolgend dargestellt.

char myText[] {"C-String"};

Das char-Feld wird dann so groß dimensioniert, dass der C-String, einschließlich der abschließenden 0, darin Platz findet.

Um z.B. einen C-String in ein char-Feld zu kopieren wird die Funktion

char* strcpy(char *pDest, const char *pSource);

verwendet. pDest ist ein char-Zeiger auf den Speicherbereich, in den der durch pSource adressierte C-String kopiert wird. pDest muss immer ein char-Zeiger auf ein Feld sein, während pSource entweder ein C-String Literal oder die Adresse eines weiteren char-Feldes sein kann.

// notwendig fuer VS, das strcpy() ansonsten einen Fehler
// ausloest, da VS die nicht standardisierte Funktion
// strcpy_s verlangt!
#pragma warning(disable : 4996)

#include <iostream>
using std::cout;
using std::endl;

int main()
{
    // Feld fuer C-String definieren mit max. 79 Zeichen
    char text[80];
    // C-String Literal in Feld kopieren
    strcpy(text, "Kopierter Text");
    // Text ausgeben
    cout << "Text im Feld: " << text << endl;
    // Alle Kleinbuchstaben in Grossbuchstaben umwandeln
    for (auto index = 0; index < strlen(text); index++)
        text[index] = toupper(text[index]);
    // Umgewandelten Text ausgeben
    cout << "Alles in Grossbuchstaben: " << text << endl;
}

range-for Schleife

Zum sequentiellen Durchlaufen eines Feldes stellt C++ eine besondere Schleife zur Verfügung, die range-for Schleife. Sie hat folgende Syntax:

for (DTYP var: array)
    ANWEISUNG;

Der Inhalt jedes Feldelements des Feldes array wird nacheinander in var abgelegt und anschließend die Anweisung ANWEISUNG ausgeführt. Dabei muss DTYP mit dem Datentyp des Feldes übereinstimmen oder sich in diesen konvertieren lassen. Mehrere Anweisungen sind in einem Block {...} einzuschließen. Soll der Inhalt des Feldelements innerhalb der Schleife verändert werden, so ist für var eine entsprechende Referenzvariable einzusetzen.

// notwendig fuer VS, das strcpy() ansonsten einen Fehler
// ausloest, da VS die nicht standardisierte Funktion
// strcpy_s verlangt!
#pragma warning(disable : 4996)

#include <iostream>
using std::cout;
using std::endl;

int main()
{
    // Feld fuer C-String definieren
    // Jetzt einmal mit Initialisierung
    char text[] { "Kopierter Text" };

    // Text ausgeben
    cout << "Text im Feld: " << text << endl;
    // Alle Kleinbuchstaben in Grossbuchstaben umwandeln
    // Nun mit range-for Schleife
    // Die Variable muss eine Referenzvariable sein, da
    // ihr Inhalt veraendert wird!
    for (auto& letter : text)
        letter = toupper(letter);
    // Umgewandelten Text ausgeben
    cout << "Alles in Grossbuchstaben: " << text << endl;
}



Copyright © cpp-tutor.de
Impressum &Datenschutz