Home » Tutorials » Object Pascal/RTL » Delphi-Crashkurs

Delphi-Crashkurs

Arrays

Ein Array ist in praktisch jeder Programmiersprache eine wichtige Möglichkeit, Daten strukturiert abzulegen. Ein Array besteht aus beliebig vielen Elementen. Diese Elemente besitzen alle eine eindeutige „Adresse“ in diesem Array, welche ein Tupel aus n Zahlen ist. Dabei ist n die Dimension des Arrays.
Mit dieser Information kann man sich ein Array natürlich noch nicht wirklich vorstellen. Daher möchte ich hier ein paar einfache Beispiel nennen. Zuerst die einfachste Variante, das eindimensionale Array: das kann man sich vorstellen, wie eine Tabelle mit nur einer Spalte:

 Wert [1]
    Wert [2]
    Wert [3]
    Wert [4]

So sähe ein eindimensionales Array aus. Jedem Element ist genau eine Zahl zugeordnet, also ein Tupel aus nur einer Zahl. Ein zweidimensionales Array kann man sich auch noch gut vorstellen. Das ist einfach eine Tabelle mit Zeilen und Spalten:

 Wert [1,1]    Wert [1,2]    Wert [1,3]
    Wert [2,1]    Wert [2,2]    Wert [2,3]
    Wert [3,1]    Wert [3,2]    Wert [3,3]

Für dieses Array benötigt man bereits ein Paar von Zahlen, um einen Wert eindeutig zu identifizieren. Man sieht leicht, dass die Anzahl der Elemente, die ein Array enthält, unabhängig von der Dimension ist. Man könnte in obiger „Tabelle“ beliebig viele Spalten und Zeilen hinzufügen und sie bliebe immer noch zweidimensional. Die Dimension eines Array gibt einfach nur an, wieviel Zahlen ich brauche, um ein Element eindeutig zu identifizieren.
Die Elemente eines Arrays spricht man an, indem man zuerst den Namen des Arrays schreibt und dann in eckigen Klammern dahinter das Zahlentupel, welches dem Element entspricht. Dabei werden die Zahlen durch Kommata getrennt. Im Prinzip also so, wie es schon in obigen Beispielen getan wurde, nur dass man die Leerzeichen weglässt.

Dynamisch oder statisch?

In Delphi unterscheiden sich Arrays nicht nur nach ihrer Dimension, sondern auch danach, ob sie „statisch“ oder „dynamisch“ sind. Bei einem statischen Array sind sowohl Dimension als auch die Anzahl der Elemente von Anfang an bekannt und können während des Programmablaufs nicht mehr geändert werden. Dynamische Arrays sind dagegen in der Lage, ihre Größe (aber nicht ihre Dimension) zu ändern.
Wenn man von einem zweidimensionalen Array ausgeht, muss ich bei einem statischen Array vorher festlegen, wieviele Zeilen und Spalten dieses Array hat. Bei einem dynamischen Array muss ich nur festlegen, dass das Array Zeilen und Spalten besitzt. Die Anzahl der Zeilen und Spalten (also die Größe des Arrays) ist veränderbar: dynamisch.
Ich möchte im folgenden zuerst die Verwendung von dynamischen Arrays demonstrieren und hinterher nur noch kurz die Unterschiede zwischen der Verwendung von dynamischen und statischen Arrays aufzeigen.

Dynamische Arrays

Deklaration

Um ein dynamisches Array zu benutzen, muss man es, wie jede andere Variable auch, erst einmal deklarieren. Die Deklaration eines Arrays besteht aus der Angabe, dass es sich überhaupt um ein Array handelt und aus der Angabe, von welchem Typ die Elemente sind. Dabei ist als Typ der Elemente jeder Datentyp erlaubt. Die Deklaration eines dynamischen, eindimensionalen Integer-Array sieht dann so aus:

var myIntArray : Array of Integer;

Ein mehrdimensionales Array wird ähnlich deklariert. Jedoch deklariert man es so, dass man z.B. für ein zweidimensionales Array ein Array in einem Array deklariert. Die Deklaration sieht dann so aus:

var my2DIntArray : Array of Array of Integer;

Wie muss man sich das vorstellen? Um das zu klären, möchte ich noch einmal das „tabellenartige“ Array von oben herauskramen. Dies lässt sich auch so schreiben:

 Array [1]   |    Array [1]   =   Wert [1]    Wert [2]    Wert [3]
    Array [2]   |    Array [2]   =   Wert [1]    Wert [2]    Wert [3]
    Array [3]   |    Array [3]   =   Wert [1]    Wert [2]    Wert [3]

Also ist ein zweidimensionales Array nichts anderes, als ein eindimensionales Array, welches als Elemente wieder Arrays hat. Der Datentyp der Elemente ist ganz einfach „Array of …“.
Damit wäre das Array auch schon deklariert. Mehr ist nicht nötig. Bei statischen Arrays geht es etwas anders, aber darauf gehe ich, wie gesagt, später noch ein.

Die Größe eines Arrays ändern

Um ein dynamisches Array zu benutzen, muss man erst einmal die Größe festlegen, welche zu Anfang in jeder Dimension Null ist. Die Größe eines solchen Arrays legt man mit dem Befehl SetLength fest. Als Parameter übergibt man der Prozedur als erstes den Namen des Arrays, dessen Größe geändert werden soll und als zweites die neue Länge des Arrays:

SetLength(myIntArray, 2);

Mit diesem Quelltext setzt man die Länge des Arrays „myIntArray“ auf zwei, das heißt, es hat zwei Elemente. Wichtig: die Indizierung eines dynamischen Arrays beginnt immer bei Null! Das heißt, die Elemente des obigen Arrays haben die Nummern 0 und 1.
Um mit einem zweidimensionalen, dynamischen Array zu arbeiten, muss man dessen Größe in beiden Dimensionen festlegen, da die Größe zu Anfang in beiden Dimensionen Null ist. Dies geht ganz analog zum Vorgehen bei nur einer Dimension, wenn man sich erinnert, wie dieses aufgebaut ist.

SetLength(my2DIntArray, 3);
SetLength(my2DIntArray[0], 1);
SetLength(my2DIntArray[1], 5);
SetLength(my2DIntArray[2], 7);

Dieser Quelltext setzt in der ersten Zeile die Größe in der obersten Ebene des Arrays (die linke Seite bei der Darstellung des 2D-Arrays von oben) auf drei und setzt dann die Größe der drei Elemente dieser Ebene, also den dynamischen Arrays, die in my2DIntArray enthalten sind (die rechte Seite bei der Darstellung des 2D-Arrays von oben). Jedoch wird hier kein „rechteckiges“ Array erstellt, sondern die einzelnen Zeilen sind nicht gleich lang.
Das mit diesem Quelltext erstellte Array sieht so aus:

 x
 x x x x x
 x x x x x x x

Möchte man ein rechteckiges Array haben, so gibt es eine sehr praktische Überladung der Prozedur „SetLength“. Sie erhält ein Argument mehr, nämlich die Länge der „untergeordneten“ Arrays. Folgender Quelltext erstellt ein „rechteckiges“ Array mit zehn Zeilen und zehn Spalten:

SetLength(mySecond2DIntArray, 10, 10);

Die Größe eines Arrays abfragen

Da bei einem dynamischen Array die Größe eine Variable ist, muss es, damit man vernünftig damit arbeiten kann, eine Möglichkeit geben, die Größe herauszufinden. Dafür bietet Delphi zwei Funktionen. „Length“ und „High„, wobei „Length“ die Größe des Arrays ist und „High“ der höchste, zulässige Index. Bei einem dynamischen Arrys ist „Length“ also immer um eines Größer als „High“.

High(my2DIntArray);

Dieser Aufruf liefert 2 zurück, denn das Array enthält ja drei Zeilen! Ein Aufruf von „Length“ würde 3 zurück geben. Um den höchsten zulässigen Index der „Unterarrays“ herauszufinden, wendet man High einfach auf sie an:

High(my2DIntArray[0]);

liefert 0 zurück (weil es ja nur ein Element enthält) und

High(my2DIntArray[3]);

liefert 6 zurück. „Length“ würde 1 bzw. 7 zurückliefern.

Arrays kopieren

Ein Array zu kopieren ist nicht so trivial, wie dies bei einer Variable ist. Bei einer Variable könnte man diese einfach einer anderen zuweisen. Bei einem Array funktioniert eine solche Zuweisung nicht! Eine Zuweisung wie diese

array1 := array2;

hätte ganz einfach den Effekt, dass nun „array1“ ein Synonym für „array2“ ist, dass heißt, dass „array1“ und „array2“ das selbe Array nur mit einem anderen Namen sind. „array1“ ist dann eine Referenz auf „array2“. Erinnern Sie sich an „call by reference“!
Aber natürlich gibt es eine Möglichkeit, auch ein Array zu kopieren und zwar mit der Funktion „copy„. Diese erhält wahlweise einen oder drei Parameter. In der ersten Variante ist der einzige Parameter das zu kopierende Array, bei der zweiten Variante wird angegeben ab welchem Index wie viele Elemente kopiert werden sollen. Zwei Beispiele machen das deutlicher:

 array1 := Copy(array2);       //kopiert array2 komplett in array1
  array1 := Copy(array2, 3, 4); //kopiert 4 Elemente beginnend mit Index 3

Aber Vorsicht: wenn ein Array einen Refernzdatentyp enthält, müssen die Elemente einzeln kopiert werden, dann erstellt auch Copy nur ein Array, welches Referenzen auf die selben Objekte enthält.

Statische Arrays

Deklaration

Die Deklaration von statischen Arrays ist nicht viel schwerer als die Deklaration von dynamischen Arrays. Man muss jedoch bei statischen Arrays die Größe mit angeben. Außerdem kann man auch den kleinsten Index angeben, dieser muss also nicht unbedingt 0 sein. Den kleinesten Index eines Arrays erhalten Sie übrigens über die Funktion „Low“.

 my2DIntArray : Array[5..17, 9..20] of Integer;
  my2DIntArray : Array[5..17] of Array[9..20] of Integer;

Beide Deklarationen ergeben das selbe Array. Eine Aufruf von „SetLength“ ist weder nötig noch möglich.

Arrays kopieren

Bei statischen Arrays gibt es eine gute und ein schlechte Nachricht. Die Schlechte wie immer zuerst: der Copy-Befehl funktioniert nicht. Man muss also im Allgemeinen jedes Element einzeln kopieren. Und nun die Gute: manchmal braucht man das doch nicht. Denn dann, wenn das Arrays ausschließlich primitve Datentypen enthält (also Boolean, Integer, Char, …), erzeugt eine einfache Zuweisung bei einem statischen Array eine Kopie des Arrays und nicht nur eine Referenz! In diesem Fall kann man ein Array also wie eine normale Variable kopieren.

2 Gedanken zu „Delphi-Crashkurs“

  1. Guten Morgen,

    erst einmal vielen Dank für die ausführlichen Erklärungen!

    Im ersten Beispiel zur Darstellung von Zahlen im Rechner müsste es heißen

    4 mal 1 = 4*10^0

    statt

    4 mal 1    = 4*10

     

    1. Vielen Dank für den Hinweis.
      Ich habe es entsprechend korrigiert.
      Auch Deinen weiteren Hinweis habe ich eingearbeiotet.

Kommentare sind geschlossen.