Array-Funktionen im Display-Interpreter

(verfügbar seit Juli 2004, siehe Feature Matrix)

  1. Übersicht
  2. Zugriff auf Werte in einem Array
  3. Arrays als Argumente in einem Funktionsaufruf
  4. Ändern der Dimensionen eines Arrays während der Laufzeit
  5. Anzeige des Inhalts von 'arr[][][]' im Programmiertool

Siehe auch:



Übersicht

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:

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.


Zugriff auf Werte in einem Array

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.

Zugriff auf einzelne Werte im Array

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.

Zugriff auf einen Bereich von Zellen im Array

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 als Argumente in einem Funktionsaufruf

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


Ändern der Dimensionen eines Arrays

Per default ist das globale numerische Array ("arr") folgendermaßen aufgeteilt:

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

Anzeige des Inhalts von 'arr[][][]' im Programmiertool

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.)


Rechtliche Hinweise

Siehe Handbuch (englischsprachige Originalversion)


Letzte Änderung: 2021-03-30 (YYYY-MM-DD)

zurück zur Übersicht