SPS-Programmierung #08: Pointer und Referenzen — Transcript

Dieses Video erklärt anschaulich Pointer und Referenzen in SPS-Programmierung und deren praktische Anwendung.

Key Takeaways

  • Pointer ermöglichen den direkten Zugriff und die Veränderung von Variablenwerten über deren Speicheradressen.
  • Referenzen sind einfache Aliasnamen, während Pointer explizit Speicheradressen speichern.
  • Funktionen können über Pointer Variablen im aufrufenden Programm verändern, nicht nur Kopien.
  • Pointer sind essenziell für die Übergabe und Steuerung komplexer Datenstrukturen in SPS-Programmen.
  • Das Verständnis von Speicheradressen und Dereferenzierung ist grundlegend für fortgeschrittene SPS-Programmierung.

Summary

  • Pointer sind Variablen, die Adressen anderer Variablen speichern, Referenzen sind Aliasnamen für bestehende Variablen.
  • Erklärung der Speicheradressierung und wie Pointer Adressen speichern und dereferenziert werden.
  • Demonstration der Deklaration und Initialisierung von Integer-Variablen und Pointern in ST.
  • Erläuterung der Dereferenzierung zur direkten Manipulation von Variablenwerten über Pointer.
  • Beispiel einer Funktion, die mittels Pointer eine Variable im Hauptprogramm verändert.
  • Vorstellung eines Funktionsbausteins FB Blink, der ein Blinksignal erzeugt.
  • Erklärung eines weiteren Funktionsbausteins FB Control, der den Blinker steuert und Zustände verwaltet.
  • Diskussion der Notwendigkeit, Pointer für die Übergabe komplexer Datenstrukturen wie Funktionsbausteine zu verwenden.
  • Hinweis auf Speichergrößenunterschiede von Adressen auf 32- und 64-Bit-Systemen.
  • Praktische Beispiele verdeutlichen den Nutzen von Pointern in der SPS-Programmierung.

Full Transcript — Download SRT & Markdown

00:00
Speaker A
Pointer sind Variablen, die Adressen von anderen Variablen speichern und Referenzen sind eigentlich nichts anderes als Alias Namen.
00:10
Speaker A
Also andere Bezeichner für schon bestehende Variablen. Okay, jetzt ist vermutlich noch gar nichts klar für euch, was heißt das eigentlich genau Adressen von Variablen und Alias Namen und wie erstellt man eigentlich Pointer und Referenzen und wofür braucht man eigentlich Pointer und Referenzen?
00:29
Speaker A
Diese Fragen versuche ich für euch hier möglichst anschaulich in diesem Video zu beantworten. Okay, zuerst will ich für euch jetzt nachvollziehbar machen, was die Aussage Pointer sind Variablen, die Adressen von anderen Variablen speichern, eigentlich genau bedeutet.
00:39
Speaker A
Dazu deklariere ich hier in dem Programm zunächst eine Integer Variable N war, das könnte auch jeder andere Datentyp sein, das spielt jetzt hier erstmal keine Rolle.
00:51
Speaker A
So und die Variable initialisiere ich mit einem Wert 3 und dann lege ich noch eine zweite Variable an mit dem Bezeichner Pointer to Int und die hat den Datentyp Pointer auf einen Integer.
01:05
Speaker A
Also eine Variable vom Typ Pointer auf einen Integer.
01:12
Speaker A
Die Variable initialisiere ich auch.
01:20
Speaker A
Und jetzt kommt's, ein Pointer speichert eine Adresse einer anderen Variablen, also muss ich hier eine Adresse zuweisen und dafür nehme ich jetzt die Adresse von N war, die Adresse einer Variablen kann man also mit dem Adressoperator ADR auslesen.
02:02
Speaker A
So das Programm lasse ich jetzt laufen und dann seht ihr hier in der Anzeige die beiden Variablen, nämlich N war und Pointer to Int und deren Werte, N war hat den Wert 3 und Pointer to Int speichert diese lange Zahl hier und das ist eine Adresse, also die Adresse unter der die Variable N war im Speicher zu finden ist, wie das jetzt hier rechts dargestellt ist.
02:26
Speaker A
Ein Speicher könnt ihr euch also als eine Art Tabelle vorstellen, jede Zeile ist hier ein Speicherplatz, in den typischerweise genau ein Byte passt.
02:39
Speaker A
Und der über eine eindeutige Adresse gekennzeichnet ist, die Variable N war ist ein Integer und ein Integer braucht zwei Byte, also ist der Wert von 3 von N war hier auf einen zusammenhängenden Bereich von zwei Zeilen verteilt.
03:18
Speaker A
Die Adresse einer Variablen ist immer die Adresse des ersten Speicherplatzes des gesamten Bereichs, den die jeweilige Variable im Speicher einnimmt und in meinem Beispiel ist es also diese hier.
03:41
Speaker A
Die Adresse wird vom Betriebssystem beim Programmstart vergeben und die ist in der Regel bei jedem Start unterschiedlich, wenn ihr das Beispiel hier nachvollzieht, wird bei euch also auch hier eine ganz andere Adresse stehen.
04:01
Speaker A
Bei 64 Bit System, was ich hier verwende, ist die Adresse 8 Byte groß, bei 32 Bit System wäre die Adresse nur 4 Byte groß.
04:10
Speaker A
So in meinem Mini Programm hier habe ich ja noch eine zweite Variable, nämlich Pointer to Int und das ist ein Pointer, der eine Adresse einer anderen Variablen speichert.
04:26
Speaker A
Diese Pointer Variable liegt auch irgendwo im Speicher, der Platz dafür wurde also auch beim Programmstart vergeben und der Wert ist gerade die Adresse von N war und die ist, wie ich gerade schon erklärt habe, so groß, dass dafür im Bereich von 8 Byte reserviert werden muss.
04:59
Speaker A
Eine Pointer Variable ist also bei 64 Bit System immer 8 Byte groß, egal ob es ein Pointer auf eine Bool Variable oder ein Pointer auf einen Long Integer oder ein Pointer auf ein Array ist, der gespeicherte Wert ist ja immer nur eine Adresse.
05:18
Speaker A
Okay, soweit so gut, aber was kann man jetzt eigentlich mit so einem Pointer machen?
05:26
Speaker A
Man kann z.B. über den Pointer auf den Wert der Variablen zugreifen, deren Adresse im Pointer gespeichert ist.
05:36
Speaker A
Das nennt man Dereferenzierung und der Dereferenzierungsoperator in ST ist dieses Dach hier.
05:55
Speaker A
Bei dem Programm hier passiert folgendes.
06:10
Speaker A
Sobald B Reset auf True gesetzt wird, lese ich über den Pointer per Dereferenzierung den Wert von N war aus und schreibe den in die Buffer Variable N Buffer.
06:35
Speaker A
Und anschließend setze ich N war wieder per Dereferenzierung auf Null.
06:42
Speaker A
Gut, jetzt habt ihr hoffentlich erstmal das grundlegende Prinzip von Pointern verstanden, aber ihr könnt jetzt mit Recht einwenden, dass das ja ein ziemlich komplizierter Weg ist, den Wert einer Variablen zu verändern.
06:57
Speaker A
Also, was ist denn jetzt ein sinnvoller Anwendungsfall von Pointern?
07:15
Speaker A
Stellt euch dazu mal vor, dass ihr eine Funktion habt, ähnlich wie diese hier, an die ihr eine Variable A übergebt, so und in der Funktion soll dann etwas passieren, also es wird z.B. etwas berechnet und am Ende dieser Berechnung soll dann der Wert der übergebenen Variablen verändert werden, so vielleicht auf Null zurückgesetzt werden.
07:36
Speaker A
Diese Funktion rufe ich dann aus dem Main Programm auf.
07:45
Speaker A
So jetzt starte ich das Programm und da seht ihr, dass der Wert von N war nicht verändert wird.
07:55
Speaker A
Wenn ich B Reset auf True setze.
08:06
Speaker A
Das liegt nämlich daran, dass A nur eine Kopie von N war ist und wenn in der Funktion der Wert von A verändert wird, bleibt N war dabei aber unverändert.
08:23
Speaker A
So die Funktion muss also Zugriff auf N war bekommen und das mache ich jetzt mit dem Pointer.
08:34
Speaker A
Ich verändere hier also den Typ des Input Parameters in Pointer auf Int und im Anweisungsteil verwende ich dann die Dereferenzierung, um den Wert auf den A zeigt zu setzen.
08:43
Speaker A
Im Main Programm muss ich jetzt den Funktionsaufruf auch anpassen, weil ja jetzt nicht mehr eine Integer Variable, sondern ein Pointer darauf erwartet wird.
08:52
Speaker A
So dann starte ich das Programm erneut.
09:01
Speaker A
Und jetzt seht ihr, dass das Zurücksetzen der Variablen N war über die Funktion Reset geklappt hat.
09:10
Speaker A
Okay, dieses Beispiel zeigt hoffentlich schon etwas besser, wofür man Pointer gebrauchen kann.
09:20
Speaker A
Um das noch klarer zu machen, gebe ich euch noch ein zweites Beispiel dazu.
09:31
Speaker A
In diesem Main Programm hier habe ich einen Funktionsbaustein FB Blink.
09:43
Speaker A
Und die Implementierung dieses FBs seht ihr hier auf der rechten Seite.
09:53
Speaker A
Der Baustein soll eine Bool Ausgangsvariable B Blink im Takt von T Period hier ein- und ausschalten.
10:06
Speaker A
Aber nur dann, wenn das Eingangssignal B Run auf True gesetzt ist.
10:16
Speaker A
So im Main Programm habe ich neben der Instanz des Blinker Bausteins noch diese Bool Variable B Blink Out, der ich das Ausgangssignal des Blinkers zuweise.
10:28
Speaker A
Die Steuerung des Blinkers, also das Starten und Stoppen und die Vorgabe der Frequenz, will ich jetzt aber nicht im Main Programm vornehmen, sondern das soll aus einem weiteren Funktionsbaustein heraus passieren.
10:40
Speaker A
Diesen Funktionsbaustein nenne ich FB Control und den habe ich hier schon rechts dargestellt.
10:50
Speaker A
Dieser Control Baustein bekommt einen Blinker als Input.
11:00
Speaker A
Ihr ahnt wahrscheinlich schon, dass die Übergabe des Blinker Bausteins in dieser Form hier nicht ganz richtig ist, aber für die Erklärung lasse ich das vorerst so.
11:13
Speaker A
So und die internen Variablen sind hier ein Timer, mit dem ich gleich bestimme, wie lange der Blinker an und aus ist und noch eine Integer Variable N State, die die Zustände des Control Bausteins repräsentiert.
11:37
Speaker A
Der FB Control hat also zwei Zustände.
11:45
Speaker A
Nämlich ein Zustand, indem der Blinker läuft.
11:55
Speaker A
Hier soll der Blinker also für eine Dauer von 3 Sekunden an sein und dabei mit einer Periode von 500 Millisekunden blinken.
12:16
Speaker A
So und wenn die 3 Sekunden abgelaufen sind, wird der Timer zurückgesetzt und es erfolgt der Wechsel in den Zustand 1.
12:30
Speaker A
Und in dem wird der Timer wieder mit einer Dauer von 3 Sekunden gestartet, aber der Blinker bleibt hier aus.
12:46
Speaker A
So nach 3 Sekunden wird der Timer wieder zurückgesetzt und der FB geht in den Zustand Null, wo also alles wieder von vorne beginnt.
12:59
Speaker A
So das heißt, der Control Baustein schaltet also den Blinker immer für 3 Sekunden an und aus und wenn der Blinker an ist, blinkt er eben zweimal pro Sekunde.
13:14
Speaker A
So im Main Programm muss ich nur noch den FB Control instanziieren und der Instanz den FB Blinker zuweisen.
13:27
Speaker A
So, jetzt läuft das Programm, aber wie ihr seht, wird das Signal B Blink Out im Main Programm nicht umgeschaltet.
13:36
Speaker A
Was ich also vorhatte, nämlich den Blinker aus dem FB Control heraus anzusteuern, geht so nicht.
13:49
Speaker A
Das Problem liegt hier im FB Control, der nämlich ein Pointer auf den Blinker übergeben bekommen muss, um den Blinker, der im Main Programm deklariert ist, auch tatsächlich steuern zu können.
14:03
Speaker A
Dazu muss ich also hier im Deklarationsteil von FB Control die Input Variable zu einem Pointer to FB Blink machen.
14:18
Speaker A
Und im Anweisungsteil muss ich dann Blinker erst dereferenzieren, um darauf zugreifen zu können.
14:30
Speaker A
So und im Main Programm muss ich dann nur wieder die Adresse vom Blinker übergeben, weil ja die Input Variable in dem FB hier vom Typ Pointer to FB Blink ist.
14:42
Speaker A
So und jetzt lasse ich das Programm wieder laufen.
14:53
Speaker A
Und dann seht ihr, dass die Variable B Blink Out im Main Programm auch tatsächlich umgeschaltet wird.
15:03
Speaker A
Wenn das jetzt nicht ganz genau im Takt ist, liegt das nicht etwa daran, dass die SPS keine Echtzeitanforderung mehr einhalten würde.
15:12
Speaker A
Sondern das ist diese Anzeige hier, die nicht in Echtzeit aktualisiert wird.
15:20
Speaker A
So dieses Beispiel hier mit dem Blinker und dem Control Baustein ist tatsächlich sehr praxisnah.
15:30
Speaker A
Der FB Blink könnte hier nämlich stellvertretend stehen für einen Baustein, über den ein Aktor angesteuert wird und der FB Control könnte ein FB sein, indem eine Steuerungslogik implementiert ist.
15:48
Speaker A
Diese Struktur wäre also ein erster Schritt, um die Steuerungslogik von der Hardware zu entkoppeln, worauf ich in weiteren Videos zur Objektorientierten Programmierung noch genauer eingehe.
16:02
Speaker A
Eine letzte Sache zu Pointern will ich hier noch erwähnen.
16:10
Speaker A
Und zwar kann man mit Pointern auch rechnen oder besser gesagt, man kann Pointer inkrementieren und dekrementieren.
16:20
Speaker A
Also erhöhen bzw. erniedrigen.
16:25
Speaker A
Das Ganze nennt man Pointer Arithmetik und ist eigentlich nur im Zusammenhang mit Arrays wirklich sinnvoll.
16:32
Speaker A
Warum?
16:34
Speaker A
Weil ein Array im Speicher immer einen zusammenhängenden Bereich einnimmt, z.B. dieses Integer Array hier mit sechs Elementen, in dem die Zahlen von 1 bis 6 gespeichert sind.
16:45
Speaker A
Ein Pointer auf dieses Array ist ja identisch mit dem Pointer auf die erste Integer Zahl, die hierin gespeichert ist.
16:57
Speaker A
Wenn man jetzt diese Adresse um den Wert von 2 Byte, also genau der Größe einer Integer Variablen erhöht, dann landet man im Speicher beim zweiten Integer Wert, der in dem Array gespeichert ist.
17:06
Speaker A
Und so kann man sich ausgehend von der Startadresse eines Arrays durch das gesamte Array durchhangeln und auf alle Elemente zugreifen.
17:17
Speaker A
Eine wichtige Sache muss man dabei beachten, nämlich muss man wissen, wie lang das Array denn genau ist, damit man nicht versehentlich den Pointer über den Bereich des Arrays hinaus inkrementiert.
17:26
Speaker A
Was möglich ist, aber dann dazu führen kann, dass man auf Speicherbereiche zugreift, auf die man gar nicht zugreifen darf.
17:31
Speaker A
Das kann nämlich wieder zu Programmabstürzen führen.
17:35
Speaker A
So, damit ihr einmal seht, wie diese Pointer Arithmetik tatsächlich aussieht, programmiere ich einmal das Beispiel, dass ich gerade erklärt habe.
17:44
Speaker A
Im Main Programm habe ich zunächst das Array N Array deklariert und initialisiert.
17:53
Speaker A
Und dann einen Pointer Pointer Start angelegt, der auf das erste Element in dem Array zeigt.
18:03
Speaker A
Dann brauche ich gleich noch weitere Variablen, nämlich einen Pointer Pointer Item, indem ich nacheinander die Adressen der Elemente in dem Array speichere.
18:14
Speaker A
Und dann noch eine Integer Variable Well Item, in die ich die Werte der Elemente des Arrays kopiere.
18:24
Speaker A
Und mit B Move initialisiere ich das Versetzen des Pointers und Index ist eine Zählervariable.
18:35
Speaker A
So, wenn also B Move auf True gesetzt wird, dann berechne ich hier zunächst die Adresse des nächsten Elements in dem Array.
18:48
Speaker A
Dazu addiere ich auf Pointer Start Index - 1 mal die Größe der Variablen, die ich durch Dereferenzierung von Pointer Start hole.
19:04
Speaker A
Also das sind 2 Byte und mit dem Wissen, dass in dem Array Integer Variablen gespeichert sind.
19:13
Speaker A
Hätte ich hier auch Size of Integer schreiben können.
19:17
Speaker A
Im ersten Durchlauf ist Index 1, da wird also zu Pointer Start nichts addiert.
19:29
Speaker A
Dann zeigt Pointer Item also auf das erste Array Element.
19:38
Speaker A
Wenn Index erhöht wird, dann wird zu Pointer Start beim nächsten Mal 2 Byte addiert.
19:46
Speaker A
Beim zweiten Mal 4 Byte und so weiter.
19:49
Speaker A
Well Item weiß ich dann den Wert zu, der durch Dereferenzierung von Pointer Item ermittelt wird.
19:58
Speaker A
Dann wird Index noch erhöht und falls Index den Wert 7 hat, wird diese Variable dann wieder auf 1 gesetzt, um also Bereichsüberschreitung zu vermeiden.
20:08
Speaker A
So, das Programm lasse ich jetzt laufen.
20:11
Speaker A
Direkt nach dem Start der SPS seht ihr, dass Pointer Item die Adresse Null speichert, das ist also der sogenannte Null Pointer.
20:24
Speaker A
Wenn ich jetzt B Move auf True setze, bekommt Pointer Item die Adresse von Pointer Start.
20:34
Speaker A
Und per Dereferenzierung speichere ich den Wert des ersten Array Elements in Well Item.
20:43
Speaker A
Und wenn ich jetzt B Move mehrmals auf True setze, seht ihr, dass jedes Mal Pointer Item um den Wert 2 erhöht wird.
20:54
Speaker A
Und nach sechsmaligem Wechsel von B Move auf True startet das Ganze von vorne.
21:02
Speaker A
So das Wesentliche zu Pointern habe ich damit gesagt und jetzt komme ich dann also zu den Referenzen.
21:12
Speaker A
Eine Referenz wird häufig als Alias Name erklärt.
21:20
Speaker A
Aber was heißt das eigentlich?
21:23
Speaker A
Dazu greife ich noch mal das allererste Beispiel auf.
21:28
Speaker A
Hier im Main Programm habe ich wieder die Integer Variable N war mit dem Wert 3 und den Pointer Pointer to Int, in dem die Adresse dieser Variablen gespeichert wird.
21:40
Speaker A
Jetzt ergänze ich noch eine Referenz auf N war mit dem Bezeichner Ref to Int.
21:50
Speaker A
Und zudem noch einen Pointer, indem ich die Adresse von Ref to Int speichere.
21:59
Speaker A
Eine Referenz wird also mit dem Schlüsselwort Reference to gefolgt von dem Datentyp angelegt.
22:12
Speaker A
Ganz wichtig bei einer Referenz ist, dass die immer initialisiert werden muss.
22:24
Speaker A
Die Zuweisung hier hinten auf N war ist also nicht optional, sondern ist zwingend notwendig.
22:34
Speaker A
So und jetzt lasse ich dieses Programm erstmal wieder laufen.
22:37
Speaker A
Hier im Online Modus seht ihr nun das Wichtige hier in den Werten der Pointer Variablen.
22:45
Speaker A
Denn die sind identisch.
22:50
Speaker A
Das heißt also, dass N war und Ref to Int zwei Bezeichner sind, die aber beide den Bezug zu ein und derselben Integer Variablen herstellen.
23:03
Speaker A
Das seht ihr jetzt auch, wenn ich N war verändere.
23:10
Speaker A
Dann verändert sich nämlich Ref to Int gleichzeitig mit.
23:15
Speaker A
Und das Spiel geht auch anders herum, wenn ich Ref to Int ändere, dann ändert sich auch gleichzeitig N war.
23:22
Speaker A
Soweit habe ich euch also erstmal das grundlegende Verständnis zu Referenzen gegeben.
23:30
Speaker A
Aber was kann man denn damit jetzt anfangen?
23:33
Speaker A
Um eine Anwendung von Referenzen zu zeigen, nehme ich wieder das Beispiel des Blinkers.
23:40
Speaker A
Hier seht ihr jetzt noch mal die Version mit dem Pointer als Übergabeparameter im Funktionsbaustein FB Control.
23:48
Speaker A
Diesen Pointer ändere ich jetzt in eine Referenz.
23:53
Speaker A
Weil Blinker hier jetzt also eine Referenz auf ein Objekt vom Typ FB Blink ist, muss ich jetzt hier keine Dereferenzierung mehr beim Aufruf des FBs durchführen.
24:05
Speaker A
Und im Main Programm muss ich an den FB Control nun auch nicht die Adresse von FB Blinker übergeben.
24:13
Speaker A
Sondern hier übergebe ich jetzt das Objekt selber.
24:18
Speaker A
So, das Programm lasse ich jetzt wieder laufen.
24:21
Speaker A
Und hier seht ihr jetzt, dass das Programm auch mit der Referenz funktioniert.
24:30
Speaker A
Die Variable B Blink Out in Main wird also umgeschaltet.
24:37
Speaker A
Und das Umschalten wird durch den FB Control gesteuert.
24:41
Speaker A
So, was ihr aus diesen Beispielen mitgenommen haben solltet, ist das Folgende.
24:50
Speaker A
Erstens, ein Pointer ist eine Variable, die Adressen speichert und eine Referenz ist ein Alias, also einfach ein neuer Bezeichner für eine bestehende Variable.
25:00
Speaker A
Zweitens, Pointer und Referenzen funktionieren zwar unterschiedlich, deren Verwendung erfolgt in der Regel aber denselben Zweck.
25:12
Speaker A
Nämlich den Zugriff auf Objekte zu ermöglichen, im Gegensatz zu dem Zugriff auf die Kopie der Objekte.
25:19
Speaker A
Und drittens, bei der Übergabe von Objekten über einen Pointer muss man den Adressoperator verwenden und der Zugriff auf das Objekt über den Pointer erfolgt dann wiederum per Dereferenzierung.
25:30
Speaker A
Bei Referenzen ist das viel einfacher, da muss man keine Adresse ermitteln und es gibt auch keine Dereferenzierung.
25:38
Speaker A
So bis hierhin könnte man sagen, es gibt gar keinen Grund Pointer zu verwenden, wenn die Verwendung einer Referenz doch so viel einfacher ist.
25:46
Speaker A
Referenzen haben gegenüber Pointern aber auch gewisse Nachteile.
25:52
Speaker A
Ein Nachteil ist, dass eine Referenz nämlich immer initialisiert werden muss.
26:00
Speaker A
Eine Referenz kann also erst dann erzeugt werden, wenn das Objekt, das referenziert werden soll, schon existiert.
26:07
Speaker A
Bei Pointern ist das nicht so, da gibt's den Null Pointer.
26:13
Speaker A
Der also erstmal auf den Speicherplatz Null zeigt und die Wertzuweisung kann dann später erfolgen.
26:20
Speaker A
Der zweite Nachteil einer Referenz ist, dass die Übergabe per Referenz Speicheraufwendiger ist.
26:26
Speaker A
In dem Blinker Beispiel hatte die Referenz auf das Objekt FB Blinker eine Größe von 48 Byte, während der Pointer auf dasselbe Objekt nur 8 Byte hat.
26:40
Speaker A
Hier ist der Unterschied zwar nicht wesentlich, aber wenn man sehr große Objekte, z.B. auch Strukturen oder Arrays per Referenz übergibt.
26:49
Speaker A
Dann kann das die Performance des Programms schon beeinträchtigen.
Topics:SPS-ProgrammierungPointerReferenzenSpeicheradressenDereferenzierungFunktionsbausteineST ProgrammierungSPSProgrammierungChristian Stöcker

Frequently Asked Questions

Was sind Pointer in der SPS-Programmierung?

Pointer sind Variablen, die die Speicheradressen anderer Variablen speichern. Sie ermöglichen den direkten Zugriff auf die Werte dieser Variablen über ihre Adressen.

Wie unterscheiden sich Pointer und Referenzen?

Referenzen sind Aliasnamen für bestehende Variablen, während Pointer explizit die Speicheradresse einer Variablen speichern und somit flexibler für Speicherzugriffe sind.

Wofür werden Pointer in SPS-Programmen verwendet?

Pointer werden verwendet, um Funktionen Zugriff auf Variablen im Hauptprogramm zu geben, komplexe Datenstrukturen zu steuern und Werte direkt im Speicher zu verändern.

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 →