2. Arrays
Bis jetzt können Sie
nur Variablen benutzen, die genau eine Zahl oder genau eine Zeichenkette
aufnehmen können. Aber was ist, wenn Sie eine Tabelle erstellen wollen, oder
eine Bestenliste für Ihr Spiel mit bis zu 20 Namen (days
best) und 20 Punkteständen für die einzelnen Namen?
Die Antwort ist, dass Sie dies bis jetzt nicht können. Aber kann man dies
überhaupt realisieren, wenn man maximal 26 Variablennamen für Strings und noch
einmal 26 Variablennamen für Zahlen zur Verfügung hat? Die Antwort ist: Man
kann, und zwar über den DIM-Befehl.
2.1 Der DIM-Befehl
DIM hat das folgende
Format:
DIM [Variablenname][$]([Größe Dimension 1],…,[Größe Dimension n])
DIM ist eine der wenigen
BASIC-Funktionen mit einer variablen Parameterliste. Variable Parameterliste
bedeutet, dass DIM beliebig viele Parameter entgegennehmen kann, solange
der Speicher hierfür ausreicht. Bei DIM werden nun (in Klammern) die
Größen der einzelnen Dimensionen eines sogenannten Datenfeldes (im
Englischen „array“) angegeben, getrennt durch
Kommata. Eine Dimension können Sie sich in der Tat wie eine Dimension in
der Mathematik vorstellen. Wenn also ein Array nur eine Dimension besitzt, dann
haben Sie nur eine Tabelle mit einer einzigen Zeile und n Spalten. Wenn Sie
dagegen zwei Dimensionen anlegen, z.B. mit
DIM A(50,50)
dann haben Sie eine
Tabelle mit 50 Zeilen und 50 Spalten angelegt. Bei drei Dimensionen dagegen
müssen Sie sich einen Würfel vorstellen, der dann auch mehrere Tabellen
enthalten kann. Allerdings übersteigen schon 4 und mehr Dimensionen unsere
Vorstellungskraft, aber mit BASIC können Sie auch 4 Dimensionen anlegen. Diese
Aussage gilt aber nicht immer, denn z.B. die BASIC-Zeile
DIM A(100,100)
frührt schon zu der Meldung
?OUT OF MEMORY
ERROR
Klar: Der
Variablen-Speicher des C64 ist beschränkt, und 10.000 Fließkomma-Zahlen belegen
auf dem C64 schon 40.000 Bytes, weil eine Zahl eben 4 Bytes belegt. Beim
Einschalten haben Sie sicherlich schon gelesen, dass 38.911 BASIC-Bytes zur
Verfügung stehen, also übersteigt ein Datenfeld von 100*100 Zahlen schon die
Speicherkapazität von BASIC. Und wenn Sie dann noch bedenken, dass ja auch Ihre
Programme Speicher belegen, dann verstehen Sie auch die folgende Warnung:
Seien Sie stets
vorsichtig mit dem DIM-Befehl und überlegen Sie immer genau, wie viele
Dimensionen Sie wirklich benötigen, denn DIM kann sehr schnell Ihren Speicher
aufzehren und sogar Ihr System zum Absturz bringen.
Diese Warnung gilt
natürlich auch für Strings, die durchaus auch in einem Datenfeld benutzt werden
können. Die Anweisung
DIM
A$(100)
ist also erlaubt, aber
unter Umständen gefährlich, weil String-Arrays dynamisch verwaltet werden. Dynamisch
bedeutet, dass wenn Sie einem String eine Zeichenkette zuweisen, der Speicher
erst jetzt angefordert wird. Dies kann dazu führen, dass Ihr Programm eine Zeit
lang sauber läuft, ab einer bestimmten Datenmenge dann aber mit OUT OF
MEMORY beendet wird. Dies ist ein sehr kritischer Zustand, der sogar dazu
führen kann, dass Ihr Programm, das Sie nun panisch mit SAVE sichern,
bevor Sie dann endgültig den Ausschalter betätigen, nicht mehr vollständig oder
sogar mit korrupten Datenstrukturen abgespeichert wird. Hier gibt es sicherlich
ein paar Tricks, die das Schlimmste verhindern können, aber im Endeffekt
sollten Sie Ihr Programm eh periodisch abspeichern, bevor Sie RUN
eingeben.
Vielleicht denken Sie
nun darüber nach, Ihr zu großes Datenfeld erst zu verkleinern (z.B. mit DIM A(1,1)), ehe Sie dann SAVE eingeben, und Ihr
Programm in Ruhe mit genug Speicher sauber auf Diskette sichern können. Leider
besitzt das C64-BASIC eine Unzulänglichkeit, die in anderen BASIC-Varianten so
nicht vorkommt: Die Fehlermeldung
?REDIM’D ARRAY ERROR
Sie können also auf dem
C64 Datenfelder nicht redimensionieren, und es gibt auch kein REDIM bzw.
realloc(), wie z.B. in C. Allerdings setzt der Befehl
RUN stets alle Datenfelder auf eine Standardgröße von einer Dimension
mit 11 Elementen zurück, und löscht auch alle String-Arrays aus dem Speicher.
Sie können also Datenfelder nicht nachträglich vergrößern oder verkleinern. Es
ist ferner auch nicht erlaubt, auf ein Datenfeld zuzugreifen, das nicht vorher
mit DIM angelegt wurde, da Arrays während des Zugriffs nicht automatisch
vergrößert werden können. Sie können also in BASIC nicht, wie z.B. in Java,
einem Array die Eigenschaft mitgeben, bei einem Zugriff auf ein ungültiges
Element automatisch REDIM oder realloc() aufzurufen, sondern hier erscheint in
diesem Fall immer der Fehler
?BAD SUBSCRIPT
ERROR
Mehr gibt es im
Endeffekt nicht über Arrays zu sagen, außer dass man wie gesagt vorsichtig mit
ihnen sein muss, aber doch nicht immer auf sie verzichten kann.