CODINGLISTINGS ★ ARRAYS VARIABEL DIMENSIONIERT ★

Arrays variabel dimensioniertCoding Listings
 ★ Ce texte vous est présenté dans sa version originale ★ 
 ★ This text is presented to you in its original version ★ 
 ★ Este texto se le presenta en su versión original ★ 
 ★ Dieser Text wird in seiner ursprünglichen Fassung Ihnen präsentiert ★ 

Oft ist zu Beginn eines Programms nicht bekannt, wieviel Elemente ein Feld maximal benötigt. Mit einer im Programmlauf veränderbaren Dimensionierung des Feldes, kann das Problem elegant und effektiv gelöst werden.

Wenn man sich als Entwickler Gedanken um die Struktur eines neuen Programms macht, ist ein wesentlicher Punkt dabei die Dimensionierung der Felder (Arrays). Steht die Zahl der Elemente von vorneherein fest, gibt es kein Problem. Meistens allerdings ist das nicht der Fall. Bei einer Textverarbeitung braucht beispielsweise ein kurzer Zweizeiler weniger Speicherplatz als ein Referat oder ein Aufsatz. Ähnliches gilt für die Anzahl von Datensätzen in einem Dateiverwaltungsprogramm oder für die Anzahl von Reihen in einer Tabellenkalkulation.

ln vielen Fällen macht es sich der Programmierer (zugegeben zwangsweise) recht einfach. Er schätz grob über den Daumen die maximal benötigte Größe ab und dimensioniert die Felder dementsprechend. Damit können dann aber auch nur Daten bis zu dem festgelegten Umfang aufgenommen Werdern. Sind mehr Werte zu verarbeiten. so »steigt« das Programm aus.

Kein Problem, werden Sie vielleicht sagen, soll er doch einfach das oder die Felder so groß machen. daß diese beim besten Willen nicht vollzukriegen sind. Das hat aber einen entscheidenden Nachteil: Schon mit der Dimensionierung wird Platz im Speicher reserviert. Dieser Platz steht, unabhängig ob er nun benötigt wird oder nicht, für andere Zwecke nicht mehr zur Verfügung. Bei der Dimensionierung von Stringarrays ist es sogar so. daß in

dem reservierten Platz nicht die Strings selbst, sondern lediglich die Stringdescriptoren (das sind Länge und Anfangsadresse eines jeden Strings. Platzbedarf drei Byte je String) gespeichert werden. Im Extremfall kann dies dazu führen, daß in einem Programm ein Stringarray mit 14000 Elementen definiert v/ird. dann aber kein Platz mehr für die Strings selbst vorhanden ist. Da der freie Spreicherplatz im Schneider mit etwa 42 KByte zwar nicht knapp, aber auch keineswegs beliebig groß bemessen ist, muß man sich immer für einen Mittelweg zwischen großzügiger und zu geringer Dimensionierung entscheiden.

Wertvoller
Speicherplatz

Wünschenswert ist also, das Feld zu Beginn klein zu dimensionieren und dann bei Bedarf Schritt für Schritt zu vergrößern. Der große Vorteil ist, daß auf diese Weise immer nur der gerade benötigte Speicherplatz belegt wird.

Das Basic hilft uns direkt nicht weiter. Ein einmal festgelegtes Feld (DIM-Feld) kann nicht mehr verändert werden. Mit ERASE steht allerdings ein natürlicher Befehl zur Verfügung, da man mit ihm Variablen beziehungsweise Felder löschen kann. Den dadurch freiwerdenden Speicherplatz hat man natürlich wieder zur Verfügung.

Mit Hilfe einer kleinen Basic- und einer Assembler-Routine kann man eine dynamische Verwaltung eindimensionaler Felder realisieren. Dabei v/ird zunächst ein zweites Feld mit der gleichen Größe wie das zu erweiternde errichtet. In dieses Hilfsfeld schreibt man alle Werte des ersten Felds. Dann wird dieses gelöscht und gleich darauf mit einer größeren Dimensionierung wieder eröffnet. Die Werte aus dem Hilfsfeld werden zurückgeschrieben und das Hilfsfeld gelöscht. Jetzt steht das erweiterte Feld zur Verfügung. Das übrige Programm merkt von dieser Änderung nichts, da der Name gleich bleibt. Da das Hin- und Herkopieren der einzelnen Elemente recht zeitaufwendig ist. übernimmt dies die Assemblenoutme.

Assembler sorgt für Geschwindigkeit

Wie kann man im Programm nun feststellen, wann der Aufruf dieser Routine fällig ist? Dazu bieten sich zwei Wege an.

Da man auf jeden Fall eine Variable braucht, die den Wert der Dimension des Feldes enthält, bietet es sich an. bei jeder Inkrementierung des Pointers, der auf das Feld zeigt, diesen Pointer mit der Dimension zu vergleichen. Ist der Wert größer. das heißt wird auf ein Element gezeigt (daher der Name Jtainter), welches noch gar nicht existiert, dann muß die Routine aufgerufen werden.

 

Als zweites kann man den Befehl ON ERROR GOTO benutzen. Dies empfiehlt sich dann, wenn der Pointer an sehr vielen Stellen im Programm benutzt wird und eine zusätzliche Abfrage an jeder dieser Stellen zu zeitintensiv ist. Beim Zugriff auf ein nicht vorhandenes Element gibt der Interpreter die Fehlermeldung Nummer 9 »Subscript out of ränge« aus. Wurde zu Beginn des Programms ein »ON ERROR GOTO« gesetzt, so ruft der Interpreter die angegebene Routine auf und übergibt in den Variablen ERR und ERL die Fehlemummer (ERR) sowie die Nummer der Zeile (ERL), in welcher der Fehler aufgetreten ist.

In dieser Routine muß nun abgefragt werden, ob der Pointer größer als die Dimensionierung des Feldes ist. Will man ganz sicher gehen, kann man die Zeilennummer (ERL) abfragen. Bei mehreren Feldern, die variabel sind, müssen diese Abfragen entsprechend mehrmals gemacht werden. Mit RESUME kann das Hauptprogramm fortgesetzt werden.

Das Beispiel aus Listing 1 kann auf die hier gezeigte Art in jedes Basic-Programm integriert werden. Es sorgt dann dafür, daß das Feld »feldS« immer ausreichend dimensioniert ist. Werden folgende Zeilen ergänzt:

351 GOTO 340
511 PRINT dimension, FRE(0)


erhält man auf dem Bildschirm sichtbar den Beweis für das stete Wachsen von »feldS«. Dabei wird die Kontrolle. wann das Feld zu vergrößern ist, von der Zeile 350 ausgeübt. Streicht man diese Zeile und verschiebt die Zeile 351 auf 361. so wird, da der Zugriff auf ein nicht definiertes Element nun nicht mehr abgefangen wird, die ON ERROR-Routi-ne aufgerufen und von hier aus das Feld vergrößert.

Alle Variablen und Feldnamen sind natürlich frei wählbar. Im Beispiel bezeichnet »dimension« die jeweils gültige Dimension des Felds »feldS«,»pointer« zeigt auf das zu bearbeitende Element aus »feldS« und »hilfS«ist das Hilfsfeld zur Aufnahme von »feldS« während der Dimensionierung. Der Abschnitt »Inkremen-tieren des Pointers« ab Zeile 320 ist nur beispielhaft gedacht. Zu beachten ist allerdings, daß. wenn der Pointer in großen Schritten (größer als ein einmaliges Erweitern des Feldes »feldS« verändert wird, die Zeile 350 durch

»350 WHILE pointer dimension:
GOSUB 420: WEND« ersetzt werden muß

In Zeile 450 muß »z0« auf 3 geändert werden, wenn ein Stringarray betroffen ist. Bei einem Integerarray beträgt der Wert 2. bei einem Real-array 5. »zl« enthält die neue Größe des Feldes. Sie jeweils um 100 Elemente zu erhöhen, ist ein unverbindlicher Vorschlag.

Zeile 460 testet den noch freien Speicherplatz. Dies ist nötig, da kurzfristig zwei Felder, eines mit der alten und eines mit der neuen, größeren Dimensionierung, nebeneinander im Speicher stehen. Falls selbst nach einer Garbage Collection (»FRE6'"i) nicht genügend Platz vorhanden ist. wird der Fehler 14 »string space full« ausgegeben.

Die Maschinencode-Routine, die die Feldinhalte verschiebt, liegt ab A000 hex im Speicher. Auch diese Adresse ist nur ein Vorschlag. Die Routine ist frei verschiebbar und kann an jede Stelle gelegt werden. Da der Aufbau von mehrdimensionalen Feldern weitaus komplizierter ist, als der von eindimensionalen (in welchen die Werte einfach aneinandergereiht sind), kann die Assembler-Routine nicht bei mehrdimensionalen Feldern benutzt werden. Sie ist dann zwar sehr einfach durch FOR......NEXT-Schleifen. die die ALL-Aufrufe ersetzen, zu simulieren. dauert aber ziemlich lange.

Fehler sinnvoll eingesetzt

Mit ein paar Änderungen kann das Programm natürlich auch dazu verwendet werden. Felder systematisch und kontrolliert zu verkleinern. Die Zeile 450 heißt dann:

450 z0 =3 : z1 = dimension - 100: dimension = z1: z2 = z0* dimension

Zum Abschluß noch der Assemblercode (Listing 2) mit Erläuterungen. Die Routine wird mit »CALL Adresse. Paraml. Param2. Param3« aufgerufen. Paraml ist der Variablenpointer des ersten Elementes in dem Feld, aus dem übertragen werden soll. Param2 ist der Variablenpointer des Zielfelds. Param3 ist die Anzahl der zu übertragenden Bytes.

Mit der Assembler-Routine kann ein Feld nur im Speicher kopiert werden. Das ist natürlich problematisch. wenn Ihre Datei mehr als 20 KByte belegt. Es ist kein Platz für das Doppel der Daten. In so einem Fall helfen folgende Basic-Zeilen:

45 OPENOUT 'nilfsf'
PRINT # 9, dimension
454 FOR i = 0 TO dinension
456 PRINT # 9, feld$(i)
458 NEXT i
460 CLOSE OUT
462 ERASE feld $
464 dimension = dimension + 100
466 DIM feld $ (dimension)
468 OPEN IN "hilfsf'
470 INPUT #9, var
472 FOR i = 0 to var
474 INPUT #9, feld$(i)
476 NEXT i
478 CLOSE IN
480 a$ = 'hilfsf'
490 IERA, @a$
500 RETURN

Die Zeilen 510 und 520 fallen dann weg.

(Matthias Engelbach/hg), HC

★ PUBLISHER: Happy Computer
★ YEAR: 1986
★ CONFIG: AMSDOS + 64K
★ AUTHOR: Matthias Engelbach

★ AMSTRAD CPC ★ DOWNLOAD ★

Type-in/Listing:
» Arrays  variabel  dimensioniert    (Happy  Computer)    LISTING    GERMANDATE: 2017-03-28
DL: 4 fois
TYPE: PDF
SIZE: 76Ko
NOTE: Uploaded by hERMOL ; 1 page/PDFlib v1.6

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding Src's » Design Grid Generator (Amstrad Computer User)
» Coding Src's » Graphic - Multicolor (CPC Amstrad International)
» Coding Src's » Memory Search (Popular Computing Weekly)
» Coding Src's » Graphic - RasterBlaster Demo
» Coding Src's » CPC Als Telefonwaehler (CPC Amstrad International)
» Coding Src's » Weaving (The Amstrad User)

QUE DIT LA LOI FRANÇAISE:

L'alinéa 8 de l'article L122-5 du Code de la propriété intellectuelle explique que « Lorsque l'œuvre a été divulguée, l'auteur ne peut interdire la reproduction d'une œuvre et sa représentation effectuées à des fins de conservation ou destinées à préserver les conditions de sa consultation à des fins de recherche ou détudes privées par des particuliers, dans les locaux de l'établissement et sur des terminaux dédiés par des bibliothèques accessibles au public, par des musées ou par des services d'archives, sous réserve que ceux-ci ne recherchent aucun avantage économique ou commercial ». Pas de problème donc pour nous!

CPCrulez[Content Management System] v8.75-desktop/c
Page créée en 042 millisecondes et consultée 94 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.