(verfügbar seit Juli 2004, siehe Feature Matrix)
- Übersicht
- Zugriff auf Werte in einem Array
- Arrays als Argumente in einem Funktionsaufruf
- Ändern der Dimensionen eines Arrays während der Laufzeit
- Anzeige des Inhalts von 'arr[][][]' im Programmiertool
Siehe auch:
Einige von MKT's programmierbaren Terminals verfügen über ein
numerisches Array, auf das per Interpreter zugegriffen werden kann.
Diese Funktionalität wurde im Sommer 2004 als Speicher für eine
spezielle Erweiterung der Diagram-Anzeige (Polygon-Overlays)
implementiert. Das Array kann allerdings auch für andere Zwecke eingesetzt
werden.
Wesentlich mächtigere Array-Funktionen stehen nur in der Script-Sprache
zur Verfügung, die Array-Funktionen des Display-Interpreter sind aber
aus Kompatibilitätsgründen weiterhin verwendbar. Um den Umstieg von 'Events'
auf die Script-Sprache zu erleichtern, kann auf das in diesem Dokument beschriebene
Array auch per Script (display.arr[row][column][component])
zugegriffen werden.
Einige Eigenschaften des in diesem Dokument beschriebenen
numerischen Arrays:
- Ein Array kann bis zu 4000 einzelne 32-bit-Fließkommawerte speichern.
Der Grund für diese Beschränkung liegt im früher verwendeten Compiler
(und der CPU), denn damals konnte die CPU maximal 16 kByte große
Speicherobjekte effizient adressieren.
- Ein Array hat drei (Index-)Dimensionen, die in diesem Dokument als Zeile
(row), Spalte (column), und Komponente
(component) bezeichnet werden.
- Per Default verwendet das globale Array des Interpreters
die in Kapitel 4 spezifizierte Aufteilung
(maximale Anzahl Zeilen, Spalten, Komponenten).
- Nach dem Einschalten enthalten alle Zellen des Arrays den Wert 0.0 (Null)
- Arrays können verwendet werden, um viele numerische Werte beim Aufruf
bestimmter Funktionen (Unterprogramme)
zu übergeben.
Die Information ob das verwendete Terminal Arrays unterstützt finden
Sie in der "Feature Matrix".
Details über Arrays in der Script-Sprache finden Sie hier.
Auf die Werte im globalen Array (namens "arr
") kann wie auf
normale Fließkomma-Variablen per Interpreter zugegriffen werden. Der
Array-Index muß in eckigen Klammern an den Namen des Arrays angehängt
werden. Die elementare Syntax für einen Arrayzugriff lautet:
arr[<Zeile>][<Spalte>][<Komponente>]
Das numerische Array ist -per Default- dreidimensional (dies könnte
sich eines Tages mit dem "dim"-Kommando ändern). Der Einfachheit halber
fassen wir die drei Dimensionen als Zeilen, Spalten und
Komponenten (=einzelne Werte) auf, wie im nachfolgend abgebildeten
10*5*4-Array (10 Zeilen, 5 Spalten pro Zeile, 4 Komponenten pro Spalte).
Die Komponenten in jeder Spalte können beispielsweise als Koordinaten
eines Punktes aufgefaßt werden, was allerdings für die nachfolgenden
Betrachtungen keine Rolle spielt. Sie können die Dimensionen in Ihrer
Anwendung nach Belieben auch anders nennen.
-
Hinweis:
-
Es ist gängige Praxis, die erste Dimension eines Arrays als "Zeile",
und die zweite als "Spalte" zu bezeichnen. Der Name der dritten Dimension ist
applikationsspezifisch. Falls das Array zur Aufnahme der Koordinaten von
Punkten dient, um z.B. Polygone in ein Diagramm
zu zeichnen, dient die dritte Arraydimension zur Aufnahme der X- und Y-Komponente
einer Koordinate. "X" ist dann Komponente 0, "Y" ist Komponente 1, "Z" (wenn
vorhanden) wäre Komponente 2, und so weiter.
Für die später folgenden Beispiele nehmen wir an, daß im
Array schon einige Werte gespeichert sind:
Inhalte des Beispiel-Arrays
(10*5*4)
|
Spalte #0 |
Spalte #1 |
Spalte #2 |
Spalte #3 |
Spalte #4 |
Zeile #0 |
0, 1, 2, 3 |
4, 5, 6, 7 |
8, 9, 10,11 |
12,13,14,15 |
16,17,18,19 |
Zeile #1 |
20,21,22,23 |
24,25,26,27 |
28,29,30,31 |
32,33,34,35 |
36,37,38,39 |
Zeile #2 |
40,41,42,43 |
44,45... |
... |
... |
... , 49 |
Zeile #3 |
60,... |
... |
... |
... |
... , 59 |
Zeile #4 |
80,... |
... |
... |
... |
... , 69 |
Zeile #5 |
100,... |
... |
... |
... |
... , 79 |
Zeile #6 |
120,... |
... |
... |
... |
... , 89 |
Zeile #7 |
140,141,142,143 |
144,145,146,147 |
148,149,150,151 |
152,153,154,155 |
156,157,158,159 |
Zeile #8 |
160,161,162,163 |
164,165,166,167 |
168,169,170,171 |
172,173,174,175 |
176,177,178,179 |
Zeile #9 |
180,181,182,183 |
184,185,186,187 |
188,189,190,191 |
192,193,194,195 |
196,197,198,199 |
Bitte beachten Sie, daß wie in der Programmiersprache "C" die Indizes
von 0 (Null) bis <Anzahl minus eins> laufen. Im Beispiel des oben
abgebildeten 10*5*4-Arrays sind die Zeilen daher von 0 bis 10 numeriert,
die Spalten von 0 bis 4, und die Komponenten von 0 bis 3.
Hier nur ein paar einfache Beispiele, wie auf einzelne Werte im Array zugegriffen
wird - genau wie in der Programmiersprache "C. Etwas interessanter wird es
später, wenn mit einer einzigen Anweisung auf mehrere Zellen "gleichzeitig"
zugegriffen wird.
-
arr[0][0][0]
-
addressiert die erste Zeile, erste Spalte, erste Komponente in einem
dreidimensionalen Array (z.B. als Teil eines
numerischen Ausdrucks). Im
oben gezeigten Beispiel steht dort der Wert 0.
-
arr[0][1][2]=6.123
-
Setzt den Wert in der ersten Zeile, zweiten(!) Spalte, dritte Komponente
im dreidimensionalen Array. Im oben gezeigten Beispiel wird dadurch der Wert
'6.0' durch den Wer '6.123' ersetzt.
Um Platz im Programmspeicher zu sparen können mehrere Zellen
(d.h. ein zusammenhängender Bereich von Array-Indizes) mit einem einzigen
Kommando gesetzt werden. Um beispielsweise alle Zellen in Zeile 0 zu setzen
(mit allen Spalten dieser Zeile, und allen Komponenten dieser Spalten), verwenden
Sie die folgende formale Zuweisung:
-
arr[0][0..4][0..3] := 0.0
-
Dieser Befehl veranlaßt den Interpreter (intern) dazu, zwei
"automatische Schleifen" zu erzeugen, um auf fünf Spalten (0 to 4) und
vier Komponenten pro Spalte (0..3) zuzugreifen. In diesem einfachen Beispiel
ist der zugewiesene Wert für alle zwanzig Zellen der gleiche (nämlich
0.0).
Um auf eine ganze Zeile zuzugreifen, können Spalten- und
Komponenten-Index auch weggelassen werden, wie im folgenden Beispiel:
-
arr[0] := 0
-
Damit werden alle Zellen einer Zeile (alle Spalten und darin enthaltene
Komponenten) gesetzt, unabhängig davon aus wie vielen Spalten + Komponenten
die Zeile besteht. Sie brauchen sich an dieser Stelle nicht um die
Dimensionen des Arrays zu kümmern.
Auf ähnliche Weise können Sie auch auf alle Komponenten
einer bestimmten Spalte setzen:
-
arr[7][0] := 0
-
Damit werden alle vier Komponenten in Zeile 7, Spalte 0 gelöscht (in
denen im obigen Beispiel die Werte 140,141,142,143
standen).
Für manche Anwendungen benötigen Sie eventuell den Index (bzw die
Indizes) bei der Berechnung des zuzuweisenden Wertes. Für diesen Zweck
können bis zu drei "automatische" Variablen verwendet werden (eine Variable
pro Dimension). Die Namen solcher Variablen dürfen im Gegensatz zu den
in der Tabelle definierten "globalen" Variablen nur aus einem einzigen
Kleinbuchstaben bestehen, wie in den folgenden Beispielen:
-
arr[i=0..9][j=0..4][k=0..3] := 20*i + 4*j + k
-
In diesem Beispiel ist "i" der von 0 bis 9 laufende Zeilenindex, "j" der
Spaltenindex (in jeder Zeile von 0 bis 4 laufend), und "k" der Komponentenindex
der hier (in jeder Spalte) von 0 bis 3 läuft. Die oben abgebildete Tabelle
wurde übrigends mit genau dieser Anweisung erzeugt. Im numerischen Ausdruck
rechts vom Gleichheitszeichen wird aus den drei Indizes (
i,j,k
)
der zuzuweisende Wert berechnet. Insgesamt wird dieser Term 200 mal
durchgerechnet, der Interpreter benötigt dafür erheblich mehr
Rechenzeit als für eine "einfache" Zuweisung.
Hinweis: Der "von-bis"-Operator (..) kann auch als Tilde (~) abgekürzt
werden, daher bewirkt
-
arr[i=0
~9][j=0
~4][k=0
~3] := 20*i + 4*j + k
-
dasselbe wie
-
arr[i=0..9][j=0..4][k=0..3] := 20*i + 4*j + k
Es folgen weitere Beispiele, wie mehrere Zellen des Arrays mit einer einzigen
Anweisung gesetzt werden können:
-
arr[0][i=0..3][j=0..1] := sdo(0x2941.(3+j+2*i),FLT) : rem read 4 pts
-
Mit dieser Anweisung werden acht Fließkommazahlen per CAN-Bus und
SDO (service data object) aus einem
anderen Gerät gelesen, wobei jede Zelle des Arrays aus einem
unterschiedlichen CANopen-Subindex stammt. Der Subindex des CANopen-Objektes
wird aus den Array-Indizes berechnet. Ohne die "internen Schleifen" beim
Arrayzugriff müßten stattdessem acht einzelne Kommandos verwendet
werden:
-
arr[0][0][0] := sdo(0x2941.3,FLT) : rem read column 0, row 0, X-coord
arr[0][0][1] := sdo(0x2941.4,FLT) : rem read column 0, row 0, Y-coord
arr[0][1][0] := sdo(0x2941.5,FLT) : rem read column 0, row 1, X-coord
arr[0][1][1] := sdo(0x2941.6,FLT) : rem read column 0, row 1, Y-coord
arr[0][2][0] := sdo(0x2941.7,FLT) : rem read column 0, row 2, X-coord
arr[0][2][1] := sdo(0x2941.8,FLT) : rem read column 0, row 2, Y-coord
arr[0][3][0] := sdo(0x2941.9,FLT) : rem read column 0, row 3, X-coord
arr[0][3][1] := sdo(0x2941.A,FLT) : rem read column 0, row 3, Y-coord
Zur Initialisierung eines Arrays mit Konstanten können auch Listen mit
individuellen Werten für die Zeilen, Spalten und Zellen verwendet werden:
-
arr[0][0..3][0..1] := {{-20,0},{0,30},{20,0},{0,-30}}
-
Damit werden vier Spalten des Arrays, mit zwei Zellen pro
Spalte (z.B. Koordinaten) zugewiesen. Beachten Sie die geschweiften
Klammern zum Trennen der Spalten und Zeilen in der Liste ! In diesem Beispiel
werden zwei ineinander geschachtelte Klammerebenen benötigt, weil zwei
unterschiedliche Dimensionen des Arrays zugewiesen werden (ähnlich wie
in der Programmiersprache "C"). Um die gleiche Initialisierung
Zelle-für-Zelle durchzuführen, würden für das oben
angeführte Beispiel acht einzelne Anweisungen benötigt:
-
arr[0][0][0] := -20 ; Zeile 0, Spalte 0, X-Koordinate
arr[0][0][1] := 0 ; Zeile 0, Spalte 0, Y-Koordinate
arr[0][1][0] := 0 ; Zeile 0, Spalte 1, X-Koordinate
arr[0][1][1] := 30 ; Zeile 0, Spalte 1, Y-Koordinate ...
arr[0][2][0] := 20
arr[0][2][1] := 0
arr[0][3][0] := 0
arr[0][3][1] := -30
zurück zur Übersicht
Arrays können zur Parameterübergabe an Unterprogramme (z.B. Funktionen)
verwendet werden, wenn "viele" Werte übergeben werden müssen. Einige
im Interpreter fest eingebaute Funktionen erwarten in der Argumentenliste
eine Anzahl von "Punkten" (mit X- und Y-Koordinate), z.B. das Kommando zum
Zeichnen von Polygons in die
Diagramm-Anzeige. Beispiel:
dia.poly(arr[0~8][0~3])
In halbwegs natürlicher Sprache bedeutet dieses Beispiel: "Hallo Diagram,
zeichne ein Polygon, nehme dazu die Koordinaten aus dem Array
arr
, aber verwende nur die Zeilen 0 bis 8, und in jeder dieser
Zeilen die Spalten 0 bis 3". Es werden also neun Polygone gezeichnet, mit
je vier Eckpunkten. Was im oben gezeigten Aufruf nicht zu sehen ist, ist
daß die X-Koordinaten aus Komponenten-Index 0, und die Y-Koordinaten
aus Komponenten-Index 1 stammen (das ist immer der Fall, wenn der
Komponenten-Index nicht explizit angegeben wird). Um zu verdeutlichen, woher
X und Y stammen, könnte man auch folgendes schreiben:
dia.poly(arr[0~8][0~3][0~1])
In dieser "vollständigen Array-Referenz" ist klar zu erkennen, daß
neun Zeilen, vier Spalten pro Zeile, und zwei Komponenten pro Spalte an das
Unterprogramm (hier: dia.poly
) übergeben werden.
-
Hinweis:
-
Im Moment gibt es nur ein einziges "globales" numerisches Array im
Interpreter. Trotzdem wird empfohlen, auch dessen Namen ("arr")
in der Parameterliste zu übergeben.
zurück zur Übersicht
Per default ist das globale numerische Array ("arr") folgendermaßen aufgeteilt:
-
100 Zeilen
-
10 Spalten pro Zeile
-
4 Komponenten pro Spalte
Die Gesamtzahl von Zellen (Fließkommawerten) im Array kann maximal
4000 betragen, weil CPU und Compiler unglücklicherweise maximal 16 kByte
große Speicherobjekte adressieren können, und eine
Fließkommazahl 4 Byte im Speicher belegt. Das Produkt aus
<Anzahl_Zeilen> * <Spalten_pro_Zeile> *
<Komponenten_pro_Spalte> darf daher nicht über 4000 liegen.
-
Hinweis:
-
Im Moment existiert nur ein einziges, "globales" Array im Interpreter.
Trotzdem wird empfohlen, auch dessen Namen ("arr")
beim Aufruf von Array-Funktionen wie z.B. "dim" mit zu übergeben.
Um die oben angegebene Aufteilung des Arrays während der Laufzeit zu
ändern, muss das Interpreterkommando "dim" verwendet werden, bevor Werte
in das Array eingetragen werden.
-
Syntax:
-
dim <Arrayname>[Anzahl Zeilen][Spalten pro Zeile][Komponenten
pro Spalte]
-
Beispiel:
-
dim arr[10][40][3]
Dimensioniert ein Array namens "arr" mit 10 Zeilen, 40 Spalten pro Zeile,
und 3 Komponenten pro Spalte.
Ein komplettes Beispiel zum Array mit "dim"-Kommando finden Sie im Verzeichnis
programs in der Datei arraytest1.cvt . Dort wird zunächst
ein Array mit 40 Spalten definiert, in dem 40 Eckpunkte für ein Polygon
abgelegt werden, welches anschließend als Polygon in ein X/Y-Diagramm
gezeichnet wird.
zurück zur Übersicht
Um während der Programmentwicklung den Inhalt von Teilen des globalen Arrays 'arr[][][]' anzuzeigen,
geben Sie im Watch-Fenster des Programmiertools
einen der weiter unten aufgeführten 'zu beobachtenden' Ausdrücke (als 'Expression') ein.
Alternativ kann im Programmiertool auch das gesamte Array aufgelistet werden
(im Hauptfenster unter Ansicht .. Globales Array).
Da im 'Watch'-Fenster immer nur eine Zeile pro Ausdruck angezeigt werden kann,
wird die Zeichenkette bei der Anzeige notfalls gekürzt. Alternativ kann der
komplette Inhalt per Kontext-Menü
in einem mehrzeiligen Textfenster angezeigt werden.
- arr[0]
- Zeigt so viele Elemente wie möglich aus der ersten Zeile an.
- arr[0][0]
- Zeigt nur den Inhalt der ersten Zeile, erste Spalte an.
- arr[0][0][0]
- Zeigt nur den Inhalt der ersten Zeile, ersten Spalte, ersten Komponente an.
- arr[0][0~NumSamples-1]
- Zeigt den Inhalt der ersten Zeile, aber nur die Spalten von Index Null bis NumSamples minus Eins.
("NumSamples" ist in diesem Beispiel eine selbstdefinierte Variable, die z.B. die Anzahl von
"Messwerten" speichert. Beachten Sie auch hier die konsequente Zählung von Indizes beginnend bei Null
- daher die Subtraktion von Eins.)
Siehe Handbuch (englischsprachige
Originalversion)
Letzte Änderung: 2021-03-30 (YYYY-MM-DD)
zurück zur Übersicht