SPS-Programmierung #06: Arrays — Transcript

Christian Stöcker erklärt in diesem Video die Verwendung von Arrays in ST: Deklaration, Initialisierung, Zugriff und Übergabe an Funktionen.

Key Takeaways

  • Arrays sind essenziell für effiziente und skalierbare Programmierung in ST.
  • Die flexible Indexierung erlaubt individuelle Anpassungen an verschiedene Anwendungsfälle.
  • Fehler bei der Indexierung können schwerwiegende Folgen haben, daher ist sorgfältige Prüfung wichtig.
  • Mehrdimensionale Arrays erweitern die Möglichkeiten, sollten aber übersichtlich bleiben.
  • Arrays können komplexe Datentypen und Funktionsbausteine enthalten und in Funktionen übergeben werden.

Summary

  • Arrays sind wichtige Datenstrukturen in ST und anderen Hochsprachen, um mehrere Variablen eines Typs zusammenzufassen.
  • Arrays ermöglichen eine effiziente Speicherverwaltung durch zusammenhängende Speicherung der Elemente.
  • Die Deklaration erfolgt mit dem Schlüsselwort ARRAY, Angabe der Größe und des Datentyps, z.B. Bool, Integer oder komplexe Typen.
  • Zugriff auf Array-Elemente erfolgt über Indizes in eckigen Klammern, wobei der Indexbereich flexibel definiert werden kann.
  • Bereichsüberschreitungen bei Array-Indizes müssen vermieden werden, da sie zu Programmfehlern oder Abstürzen führen können.
  • Arrays können initialisiert werden, indem Werte für alle Elemente in eckigen Klammern angegeben werden.
  • Komplexe Datentypen und Funktionsbausteine wie Timer können ebenfalls in Arrays verwendet werden.
  • Mehrdimensionale Arrays (z.B. zweidimensional) sind möglich und werden durch mehrere Indexbereiche definiert.
  • Die Nutzung von Arrays mit mehr als drei Dimensionen sollte vermieden werden, um die Nachvollziehbarkeit zu erhalten.
  • Arrays können als Parameter an Funktionen oder Funktionsbausteine übergeben werden, um z.B. Produkte in einem Lagerregal zu verwalten.

Full Transcript — Download SRT & Markdown

00:00
Speaker A
Arrays, also Felder von Variablen, sind auch in ST, genauso wie in vielen anderen Hochsprachen auch, ein ganz wichtiges Element der Programmierung. Hier zeige ich euch, wie man Arrays in ST verwendet, also wie man Arrays deklariert, initialisiert und wie man dann auf die einzelnen Elemente des Arrays zugreift.
00:31
Speaker A
Bevor ich jetzt ins Programmieren einsteige, erkläre ich einmal im Schnelldurchlauf, was Arrays eigentlich genau sind und wofür man die verwenden kann. Also, häufig braucht man in einem Programm nicht nur eine Variable von einem Typ, sondern gleich eine ganze Reihe davon.
01:00
Speaker A
Stellt euch mal so eine Aufzugsanlage vor mit mehreren Etagen. Auf jeder Etage gibt es einen Taster, mit dem man den Aufzug rufen kann. Jetzt könnte man für jeden Taster eine eigene Bool Variable anlegen. Das wäre aber ziemlich umständlich, weil man ja jede Variable im Programm separat behandeln muss.
01:53
Speaker A
Und außerdem wäre ein solcher Ansatz überhaupt nicht gut erweiterbar, wenn man z.B. den gleichen Code für die Steuerung auf einer Aufzugsanlage mit fünf oder nur drei Etagen übertragen wollte. Besser wäre es, wenn die Bool Variablen gleich in einem ganzen Block angelegt würden und das geht eben mit Arrays.
02:24
Speaker A
Auf diese Weise hier werden gleich vier Bool Variablen in einem Feld angelegt. Das Besondere bei Arrays ist, dass hier immer alle Variablen in einem zusammenhängenden Speicherbereich angelegt werden.
02:50
Speaker A
Während also bei meinem ersten Ansatz die vier Bool Variablen beliebig im Speicher verteilt wären, hängen bei einem Array alle hintereinander, was einen effizienten und schnelleren Zugriff auf die einzelnen Elemente möglich macht. Okay, an diesem einfachen Beispiel hier seht ihr auch schon die Syntax für die Deklaration eines Arrays.
03:33
Speaker A
Vorne steht, wie auch bei normalen Variablen, zunächst der Bezeichner und hinter dem Doppelpunkt wird dann mit dem Schlüsselwort ARRAY angegeben, dass es sich hier um ein Array handelt. In den eckigen Klammern wird dann die Größe des Arrays spezifiziert. Hier ist es ein Array der Länge 4.
04:03
Speaker A
So und dahinter steht dann von welchem Datentyp das Array ist, hier also vom Typ Bool. Da können aber auch beliebige Datentypen eingesetzt werden, also z.B. auch andere Standarddatentypen wie Integer, Real, Byte und so weiter.
04:30
Speaker A
Aber auch komplexe Datentypen, also Strukturen oder sogar Funktionsbausteine können hier als Datentyp eingesetzt werden. So hier in den eckigen Klammern wird, wie ich das gerade schon erklärt habe, die Array Größe angegeben. Gleichzeitig werden damit aber auch die Indizes definiert, mit denen ich die einzelnen Elemente, also hier die Bool Variablen adressieren kann.
05:14
Speaker A
In diesem Beispiel wäre der Zugriff auf das erste Element dieser hier. Und entsprechend wäre dann der Zugriff auf alle weiteren Elemente so. Alle Elemente des Arrays werden also über denselben Bezeichner, hier nämlich BBTN, angesprochen.
05:46
Speaker A
Aber über die eckigen Klammern dahinter wird dann das konkrete Element adressiert. Hier seht ihr den schreibenden Zugriff auf die Elemente, aber der lesende Zugriff funktioniert auf dieselbe Weise.
06:10
Speaker A
Hier weise ich also der Variablen BLocal den Wert aus dem Element mit dem Index 2 zu. In meinem Beispiel hier läuft der Index von 1 bis 4, weil das eben so in der Deklaration des Arrays angegeben ist.
06:40
Speaker A
Das kann man aber auch anders machen, also z.B. könnte man den Index auch bei 0 starten lassen, wie das bei C oder C++ z.B. typisch ist. Bei der Festlegung des Bereichs für den Index ist man also ziemlich frei, man könnte da sogar auch negative Zahlen angeben.
07:23
Speaker A
Beachten muss man dabei eigentlich nur zwei Sachen, nämlich erstens, dass der untere Index auch wirklich kleiner als der obere ist und zweitens, dass die Grenzen konstant sind. Sowas hier würde also beim Kompilieren zu einem Fehler führen, weil NMax eine veränderliche Variable ist.
08:03
Speaker A
Wenn ich aber NMax zu einer Konstanten mache, dann wäre wieder alles okay. Und genauso wie die obere Grenze, kann man auch die untere Grenze durch eine Konstante festlegen.
08:24
Speaker A
Bei der Verwendung von Arrays muss man darauf achten, dass man den Bereich für den Index, den man im Anweisungsteil verwendet, auch wirklich einhält. Unbedingt vermeiden muss man also Bereichsüberschreitungen wie diese hier. Hier habe ich also den Index 4 angegeben, der aber nicht mehr in dem Bereich ist, den ich im Deklarationsteil verwende.
09:04
Speaker A
Im besten Fall führt ein solcher Fehler zum Abbruch beim Kompilier Vorgang, im schlechtesten Fall kann eine Bereichsüberschreitung, wenn sie denn beim Kompilieren unerkannt bleibt, zu einem Programmabsturz führen und das ist insbesondere in der Anlagen- und Prozesssteuerung extrem schmerzhaft und kann auch richtig teuer werden.
09:30
Speaker A
So hier im Deklarationsteil habe ich also das Array deklariert, aber genau wie jede Variable kann ich dieses Array auch initialisieren und das macht man so. Hinter dem Datentyp erfolgt also die Zuweisung mit dem Doppelpunkt gleich.
10:00
Speaker A
Und dann werden in eckigen Klammern nacheinander durch ein Komma getrennt die Werte der einzelnen Elemente des Arrays angegeben. So zu Beginn habe ich ja gesagt, dass man ein Array auch von komplexen Datentypen oder auch von Funktionsbausteinen anlegen kann.
10:20
Speaker A
Das zeige ich euch jetzt noch mal am Beispiel von zwei Einschaltverzögerungen, die ich in einem Array zusammenfasse. Timer Array ist also ein Array mit zwei TON Funktionsbausteinen, die ich über unterschiedliche Bool Variablen starten kann und die nur unterschiedliche Verzögerung haben mit zwei bzw. vier Sekunden.
10:47
Speaker A
Und hier seht ihr also, dass ich die Timer wie gewohnt auch als Elemente eines Arrays aufrufen kann, wobei die Bezeichner der Timer Instanzen eben Timer Array von 1 und Timer Array von 2 sind. Bis hierhin habe ich euch eindimensionale Arrays vorgestellt.
11:17
Speaker A
Das sind also Arrays, bei denen man die Elemente über eine Indexvariable adressieren kann. Für manche Aufgabenstellungen benötigt man aber auch mehrdimensionale Arrays. Also stellt euch z.B. ein Lagerregal vor mit vier Fächern und in jedem Fach gibt es zehn Ablageplätze.
11:57
Speaker A
In diesem Regal sollen Produkte eingelagert werden und die Produkte sind durch eine Produktnummer, die man z.B. als DINT darstellen könnte, gekennzeichnet. Um dann also nachzuverfolgen, welches Regalfach mit welchem Produkt belegt ist, beschreibe ich das Regal durch ein zweidimensionales Array.
12:23
Speaker A
Das Array lege ich also fast genauso an, wie zuvor bei eindimensionalen Arrays, also mit Bezeichner, dann Array off und hinten kommt dann der Datentyp des Arrays, hier also ein DINT.
12:50
Speaker A
Bei den Indizes gibt's jetzt zwei Bereiche, die durch ein Komma getrennt sind. Die erste Dimension hat also einen Bereich von 1 bis 4, das sind also die Fächer und die zweite Dimension hat den Bereich von 1 bis 10, also die Ablageplätze pro Fach.
13:21
Speaker A
Für den Zugriff auf die Elemente des Arrays muss ich jetzt also zwei Dimensionen angeben, z.B. so. Okay, hier seht ihr also die Verwendung eines zweidimensionalen Arrays.
13:52
Speaker A
Auf dieselbe Weise könnt ihr Arrays noch größerer Dimension erstellen. Grundsätzlich sind also Dimensionen von 3, 4, 5 oder noch größer möglich. Allerdings solltet ihr darauf achten, dass die Datenstrukturen, die ihr in eurem Programm verwendet, nachvollziehbar bleiben.
14:22
Speaker A
Und das ist in der Regel bei Arrays ab der Dimension 4 ziemlich schwierig. So, jetzt habe ich euch erklärt, wie man Arrays deklariert, initialisiert und wie man auf die Elemente von Arrays lesend und schreibend sowohl bei ein als auch bei mehrdimensionalen Arrays zugreifen kann.
14:47
Speaker A
Jetzt werde ich euch noch zwei Sachen zeigen, die wichtig sind, wenn man Arrays an Funktionen oder an Funktionsbausteine übergibt. Und dazu schreibe ich jetzt eine Funktion, die ich nutzen könnte, um ein Produkt in das Regal einzulagern.
15:12
Speaker A
Hier habe ich also die Funktion mit dem Namen FUN_ablegen deklariert, die einen Wert vom Typ BOOL zurückgibt. Als Übergabeparameter bekommt die Funktion dann das Array, die Nummern für Fach und Platz und die Produktnummer.
15:52
Speaker A
In der Funktion checke ich dann zuerst, ob das angegebene Fach leer ist, also den Wert 0 hat und wenn das der Fall ist, dann schreibe ich in das Fach die Produktnummer und gebe TRUE zurück. Andernfalls passiert nichts und es wird FALSE zurückgegeben.
16:23
Speaker A
So, die Funktion rufe ich jetzt mal aus dem Main Programm auf. Dazu lege ich mir zusätzlich zum Regal noch zwei Bool Variablen an. Mit B_ablegen steuere ich den Aufruf der Funktion und B_done nimmt dann den Rückgabewert der Funktion auf.
17:01
Speaker A
So hier wird dann also die Funktion aufgerufen, immer wenn B_ablegen auf TRUE gesetzt wird und nach dem Aufruf setze ich B_ablegen dann automatisch wieder zurück, damit die Funktion eben tatsächlich nur einmal aufgerufen wird.
17:13
Speaker A
So, dann lasse ich jetzt das Programm mal laufen. So jetzt setze ich B_ablegen auf TRUE und schreibe den Wert in die SPS. Was ihr jetzt hier seht ist, dass die Funktion zwar ausgeführt wird, denn der Rückgabewert hier wird auf TRUE gesetzt, aber das Element in dem Regal bleibt unverändert, also hat hier noch immer den Wert 0.
17:46
Speaker A
Die Funktion macht also nicht das, was ich wollte. Wo ist also der Fehler? Der Fehler ist hier in der Funktion und zwar nicht im Anweisungsteil, sondern hier oben im Deklarationsteil. Denn die Übergabeparameter hier sind sogenannte Wertparameter.
18:26
Speaker A
Das heißt, von den Parametern, die ich übergebe, wird zuerst eine Kopie angelegt und die Funktion arbeitet dann auf der Kopie und nicht auf den ursprünglichen Daten. In dem kopierten Array wird dann also nach dem Funktionsaufruf das Element 1 1 auf den Wert 12345 gesetzt.
19:13
Speaker A
Aber das hat keine Bedeutung, denn nachdem die Funktion abgearbeitet wurde, werden die kopierten Variablen und auch eben dieses Array wieder gelöscht. Ich muss also dafür sorgen, dass die Funktion nicht in der Kopie, sondern in dem ursprünglichen Array arbeitet.
20:06
Speaker A
Das kann ich sehr einfach machen, indem ich das Array nicht als Input Variable deklariere, sondern als In-Out Variable. Jetzt gehe ich zurück in das Main Programm und starte das noch mal. Ich setze also B_ablegen wieder auf TRUE und schreibe den Wert wieder in die SPS.
Topics:SPS ProgrammierungSTArraysDatenstrukturenMehrdimensionale ArraysFunktionsbausteineTimerIndexierungInitialisierungChristian Stöcker

Frequently Asked Questions

Wie deklariert man ein Array in ST?

Ein Array wird mit dem Schlüsselwort ARRAY deklariert, gefolgt von der Größe in eckigen Klammern und dem Datentyp, z.B. BBTN : ARRAY[1..4] OF BOOL.

Kann man Arrays mit komplexen Datentypen in ST verwenden?

Ja, neben Standarddatentypen können auch Strukturen und Funktionsbausteine wie Timer in Arrays verwendet werden.

Was passiert, wenn man einen Index außerhalb des definierten Bereichs verwendet?

Das kann zu Kompilierfehlern führen oder, wenn unerkannt, zu Programmabstürzen, was besonders in der Anlagensteuerung problematisch ist.

Get More with the Söz AI App

Transcribe recordings, audio files, and YouTube videos — with AI summaries, speaker detection, and unlimited transcriptions.

Or transcribe another YouTube video here →