
Von der Grundstufe bis zur Mittelstufe: Die Anweisung SWITCH
Einführung
Der hier dargestellte Inhalt ist ausschließlich für Bildungszwecke bestimmt. Die Anwendung sollte unter keinen Umständen zu einem anderen Zweck als zum Erlernen und Beherrschen der vorgestellten Konzepte verwendet werden.
Im vorherigen Artikel „Von der Grundstufe zur Mittelstufe: Die Include-Direktive“ haben wir die Grundlagen der Verwendung der #include-Kompilierdirektive behandelt. Dieser Artikel diente als kurze Pause, die es Ihnen ermöglichte, die Informationen richtig aufzunehmen und sich die Zeit zu nehmen, um zu lernen, wie man mit Kontrollflussanweisungen arbeitet. Denn es ist in der Tat wichtig, dass Sie sich mit ihnen auseinandersetzen und genau wissen, wie sie zu verwenden sind. Wir sind jedoch noch nicht ganz fertig. Es gibt noch zwei zusätzliche Anweisungen in MQL5, die wir behandeln müssen. Sie sind etwas komplexer, vor allem in Bezug auf die Aufmerksamkeit, die ihre Verwendung erfordert.
Aus diesem Grund werde ich versuchen, beides mit größerer Sorgfalt anzugehen. Dies ist wichtig, denn selbst der kleinste Fehler, den Sie als Programmierer bei der Verwendung dieser beiden abschließenden Operatoren machen, wird mit ziemlicher Sicherheit zu einem erheblichen Zeitverlust führen, wenn Sie versuchen, den Fehler in Ihrem Code zu finden.
Wenn Sie die vorherigen Befehle als schwierig und komplex empfunden haben, sollten Sie sich darauf gefasst machen, dass die letzten beiden Befehle noch mehr Aufmerksamkeit erfordern. Am Ende dieser Artikel werden Sie jedoch zumindest verstehen, wie jeder einzelne funktioniert. Daher ist die erste Voraussetzung für die Lektüre dieses Artikels, dass Sie sich mit Variablen und Konstanten auskennen und wissen, wie man die IF-Anweisung verwendet. Wenn Sie in diesen Bereichen zuversichtlich sind, können Sie fortfahren und die hier vorgestellten Inhalte verstehen.
Beginnen wir wie üblich mit dem neuen Thema. Wir beginnen mit der Erörterung der vorletzten zu erläuternden Aussage.
Die Anweisung SWITCH
Diese Anweisung, die wörtlich „Schalter“ bedeutet, kann als mögliche Alternative zur IF-Anweisung dienen. Es gibt jedoch eine wichtige Nuance, die Sie verstehen müssen, bevor Sie die SWITCH-Anweisung effektiv anstelle von IF verwenden können.
Um zu verstehen, wann und wie diese Substitution möglich ist, ist es wichtig, dass Sie, liebe Leserin, lieber Leser, zunächst ein Schlüsselkonzept verstehen. Beim Programmieren kommt es nicht selten vor, dass wir dieselbe Variable auf der Suche nach einem ganz bestimmten Wert mehrfach testen. Diese Formulierung „sehr spezifisch“ ist hier der Kerngedanke. Der Wert kann nicht größer, kleiner oder auch nur ähnlich sein; er muss genau dem gesuchten Wert entsprechen. Nicht mehr und nicht weniger: EXAKT.
In solchen Szenarien können wir die Verwendung mehrerer IF-Anweisungen vermeiden und stattdessen eine einzige SWITCH-Anweisung verwenden. Allerdings - und das ist entscheidend - müssen Sie sich darüber im Klaren sein, dass die Bitbreite und das Format der Variablen, die in einer SWITCH-Anweisung verwendet werden, eine wichtige Rolle dabei spielen, ob diese effektiv genutzt werden kann oder nicht.
Zusammenfassend lässt sich sagen, dass Sie SWITCH nur dann als Ersatz für mehrere IF-Anweisungen verwenden können, wenn in diesen IF-Bedingungen dieselbe Variable geprüft wird. Außerdem können Sie nur prüfen, ob die Variable einem bestimmten Wert entspricht. Es ist nicht möglich zu prüfen, ob er größer oder kleiner als dieser Wert ist. Auch die Bitbreite der Variablen kann das Ergebnis der Auswertung beeinflussen. Dies ist, ganz einfach ausgedrückt, die Definition der Funktionsweise der SWITCH-Anweisung.
Auf den ersten Blick mag dies übermäßig kompliziert oder zumindest unpraktisch erscheinen. Das Gegenteil ist jedoch der Fall. Die SWITCH-Anweisung wird in vielen verschiedenen Szenarien verwendet. Auch wenn sie auf den ersten Blick begrenzt oder umständlich erscheinen mag, ist sie in vielen realen Anwendungen sehr nützlich.
Was die SWITCH-Anweisung wirklich etwas verwirrend oder einschüchternd macht, insbesondere für Programmieranfänger, ist ihr unterschiedliches Verhalten in verschiedenen Programmiersprachen und Kontexten. In diesem Artikel konzentrieren wir uns jedoch speziell darauf, wie die SWITCH-Anweisung in MQL5 verwendet wird. In diesem Zusammenhang ähnelt ihr Verhalten stark dem der SWITCH-Anweisung in C/C++. Sie können sogar die C/C++-Dokumentation als zusätzliche Ressource heranziehen, um Ihr Verständnis für dieses Konstrukt zu vertiefen. Denn was wir hier behandeln, ist nur die Grundlage, ein einführender Blick auf die Funktionsweise der Erklärung und einige Vorsichtsmaßnahmen, die zu beachten sind. Es gibt noch viel mehr zu entdecken, wenn Sie sich ansehen, wie SWITCH in C/C++ implementiert ist.
Ich glaube, das gibt Ihnen einen guten Eindruck davon, was vor Ihnen liegt und wo Sie noch tiefer einsteigen können, wenn Sie wollen. Es ist also an der Zeit, die SWITCH-Anweisung und ihre Einsatzmöglichkeiten zu erforschen. Beginnen wir mit einem sehr einfachen Beispiel, bei dem die Anweisung selbst noch nicht verwendet wird. Werfen wir einen Blick auf den unten stehenden Code:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. uchar counter = 5; 07. 08. if (counter == 5) Print("The counter value is five."); else 09. if (counter == 3) Print("The counter value is three."); else 10. if (counter == 1) Print("The counter value is one."); else 11. Print("The counter value is unknown."); 12. } 13. //+------------------------------------------------------------------+
Code 01
Ich weiß, dass viele Leser dies sehen und sagen werden: „Mann, was für ein dummes Stück Code.“ Und ja, ich weiß, das ist es. Aber wir müssen wirklich mit etwas sehr Einfachem beginnen. Andernfalls kann es passieren, dass Sie später nicht mehr wissen, was eigentlich passiert ist.
Wenn Sie sich diesen Code ansehen, können Sie gut verstehen, was im MetaTrader 5 Terminal angezeigt wird. Daher halte ich es für völlig unnötig, die Ausgabemeldung anzuzeigen. Wenn Sie, liebe Leserin, lieber Leser, es nicht allein durch das Lesen des Codes herausfinden können, empfehle ich Ihnen dringend und ohne das geringste Zögern, genau hier anzuhalten, zurückzuspulen und mit dem allerersten Artikel zu beginnen: Von der Grundstufe bis zur Mittelstufe: Variablen (I). Glauben Sie nicht, dass Sie das Programmieren lernen, indem Sie Schritte überspringen. Das werden Sie nicht. Beginnen Sie damit, die grundlegenden Konzepte und Befehle zu verstehen, bevor Sie versuchen, größere Sprünge in unbekanntes Terrain zu machen.
Also gut, machen wir weiter. An dieser Stelle können Sie deutlich sehen, dass dieser Code genau das demonstriert, was wir zu Beginn dieses Themas definiert haben. Das heißt, wir haben eine einzige Variable, die durch mehrere IF-Anweisungen ausgewertet wird. Dabei wird jeweils auf einen bestimmten Wert geprüft. Wir prüfen nicht, ob der Wert größer oder kleiner als etwas ist; wir suchen nach exakten Übereinstimmungen. Das ist der springende Punkt. Mit anderen Worten: Sobald wir eine Situation wie in Code 01 haben, können wir sie durch etwas Eleganteres ersetzen. Dieses Etwas ist die SWITCH-Anweisung.
Nachdem dies nun klar definiert und verstanden ist, wollen wir uns ein weiteres Codebeispiel ansehen, das bei der Ausführung genau dasselbe Ergebnis liefert. Es ist unten aufgeführt:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. uchar counter = 5; 07. 08. switch (counter) 09. { 10. case 5: 11. Print("The counter value is five."); 12. break; 13. case 3: 14. Print("The counter value is three."); 15. break; 16. case 1: 17. Print("The counter value is one."); 18. break; 19. default: 20. Print("The counter value is unknown."); 21. } 22. } 23. //+------------------------------------------------------------------+
Code 02
Und da haben Sie es, lieber Leser. Code 02 ist ähnlich wie Code 01 und führt zu genau demselben Ergebnis, ohne dass sich die Ausgabe in irgendeiner Weise unterscheidet. Aber Sie werden vielleicht denken: „Mann, das sieht viel komplizierter aus. Ich würde lieber bei Code 01 bleiben.“ Und ich will nicht bestreiten, dass der Code 02 auf den ersten Blick komplexer erscheint. Warum also sollte jemand beim Schreiben seiner Programme Code 02 statt Code 01 verwenden? Nun, die Antwort ist nicht ganz so einfach, wenn es um die SWITCH-Anweisung in ihrer einfachsten Form geht. Ich kann Ihnen jedoch versichern, dass es viele Szenarien gibt, in denen SWITCH deutliche Vorteile gegenüber IF hat. Das liegt daran, dass SWITCH eine Fähigkeit besitzt, die IF nicht hat: die Fähigkeit, während der Ausführung andere Werte zu verarbeiten.
Diese Art von Verhalten ist ein fortgeschrittenes Thema bei der Arbeit mit der SWITCH-Anweisung. Ich erwähne das hier nur, damit Sie SWITCH nicht von vornherein ablehnen, nur weil es verwirrend oder kompliziert erscheint. In Wirklichkeit ist es viel nützlicher, als es auf den ersten Blick scheint.
Schauen wir uns den Code 02 genauer an. Sie werden feststellen, dass hier ein paar interessante Elemente verwendet werden. Erstens: Was hat diese BREAK-Anweisung hier zu suchen? Wird BREAK nicht normalerweise innerhalb von Schleifen verwendet? Das ist richtig, lieber Leser. Die BREAK-Anweisung wird tatsächlich in Schleifen verwendet. Sie wird aber auch an bestimmten Stellen innerhalb einer SWITCH-Anweisung verwendet. Sie steuert, wie SWITCH ausgeführt wird. Genauer gesagt, wenn wir die BREAK-Anweisung verwenden, weisen wir den Compiler an, die Ausführung der aktuellen SWITCH-Routine an diesem Punkt zu beenden. Auf diese Weise weiß der Compiler genau, was er als Nächstes tun muss. In gewisser Weise ähnelt dies der Funktionsweise von BREAK in einer Schleife. Aber hier wird sie anders angewandt, je nachdem, wie die Ausführung strukturiert ist. Keine Sorge, darauf gehen wir in Kürze näher ein. Doch zuvor wollen wir über etwas anderes sprechen, das Ihnen vielleicht aufgefallen ist: die Verwendung des reservierten Schlüsselworts CASE. Wenn Sie die Codes 01 und 02 genau vergleichen, werden Sie feststellen, dass es hier eine deutliche Ähnlichkeit gibt.
Die SWITCH-Anweisung sieht ähnlich aus wie eine IF-Anweisung, und wir haben jetzt einen Block eingegeben. Das Wort CASE funktioniert ähnlich wie die Gleichheitsbedingung, die in jedem IF-Ausdruck in Code 01 verwendet wird. Nach CASE geben wir einen Wert an, der genau den Werten entspricht, die Sie in den einzelnen IF-Bedingungen gesehen haben. Interessant, nicht wahr? Und nein, das ist kein Zufall. Genau so ist die SWITCH-Anweisung gedacht und sollte in der Praxis auch so verstanden werden. Deshalb mag SWITCH auf den ersten Blick viel komplizierter erscheinen, als es tatsächlich ist. Aber wenn man erst einmal verstanden hat, wie es funktioniert, wird es ganz einfach und in der Tat sehr wirkungsvoll. Schon bald werden Ihnen neue Möglichkeiten der Anwendung einfallen.
In Code 01 hatten wir Zeile 11, die ausgeführt wurde, wenn keiner der Werte mit den erwarteten übereinstimmte. Das Gleiche passiert hier bei SWITCH. Um dieses Verhalten zu erreichen, verwenden wir ein weiteres reserviertes Schlüsselwort: DEFAULT. Innerhalb einer SWITCH-Anweisung oder eines SWITCH-Blocks teilt DEFAULT dem Compiler mit, dass eine alternative Routine ausgeführt werden soll, wenn kein Fall mit dem im SWITCH-Ausdruck getesteten Wert übereinstimmt. Normalerweise wird diese Unter-Anweisung DEFAULT am Ende des SWITCH-Blocks platziert. Dadurch wird eine logische Struktur beibehalten. Technisch gesehen können Sie sie jedoch überall innerhalb des Blocks platzieren. Es wäre nur etwas unkonventionell und unangenehm, dies zu tun.
Ziemlich interessant, oder? Es gibt noch ein weiteres Detail, das den Nutzen von SWITCH noch deutlicher machen könnte. Eine IF-Anweisung führt den zugehörigen Block nur dann aus, wenn der Ausdruck „wahr“ ergibt. Unabhängig vom Wert wird der Block nur ausgeführt, wenn die Bedingung erfüllt ist. Bei SWITCH laufen die Dinge ein wenig anders. Der Ausdruck wird in numerischer Form ausgewertet. Entscheidend ist, ob der Wert mit dem zu testenden Wert übereinstimmt. Ein CASE-Block wird nur dann und nur dann ausgeführt, wenn der Wert genau dem Ausdruck in der SWITCH-Anweisung entspricht. Dieser Block endet jedoch erst dann, wenn eine BREAK-Anweisung auftritt oder das Ende der SWITCH-Anweisung erreicht wird. Achten Sie also darauf.
Fügen Sie vorerst immer eine BREAK-Anweisung ein, bevor Sie einen neuen CASE beginnen. So bleibt Ihr Code übersichtlich und wird nicht durcheinander gebracht. Später werden wir uns mit Szenarien befassen, in denen das Weglassen von BREAK nützlich sein kann. Aber bis dahin sollten Sie es sich zur Gewohnheit machen, vor jedem neuen CASE ein BREAK zu setzen.
Schauen wir uns nun an, wie der Ausführungsablauf der SWITCH-Anweisung tatsächlich funktioniert. Dies wird in der nachstehenden Abbildung veranschaulicht:
Abbildung 01
Hier, liebe Leserin, lieber Leser, haben wir es mit etwas zu tun, das sich von dem unterscheidet, was wir in den vorherigen Ausführungsflussdiagrammen gesehen haben. Das liegt daran, dass Abbildung 01 veranschaulichen soll, wie Sie die SWITCH-Anweisung verstehen sollten. Wenn Sie also wirklich verstehen wollen, wie SWITCH funktioniert, insbesondere bevor wir uns mit fortgeschritteneren Aspekten beschäftigen, ist es wichtig, dieses Diagramm richtig zu verstehen. Wenn Sie das getan haben, werden Sie die SWITCH-Anweisung mit Leichtigkeit erforschen können, sogar auf einer Ebene, die über das hinausgeht, was wir derzeit demonstrieren.
Hier sind die Erklärungen. Wie Sie feststellen werden, beginnt alles wie bei jeder anderen Aussage auch. Das heißt, dass das reservierte Schlüsselwort verwendet wird, um den Beginn der Anweisung zu deklarieren. Von diesem Moment an, bis zum Erreichen des Ausgangspunktes (der kleine Kreis am Ende), gehört alles ausschließlich dem SWITCH-Block. Keiner dieser Befehle ist von außen zugänglich. Dies zu verstehen ist von entscheidender Bedeutung, insbesondere für ein Konzept, das wir später untersuchen werden.
Das nächste Element, dem wir begegnen, ist der Ausdruck. Dieser Ausdruck ist numerisch und nicht logisch zu interpretieren. Was bedeutet das für die Praxis? Das bedeutet, dass die Verwendung von Bedingungen wie „größer als“ oder „kleiner als“ innerhalb des Ausdrucks nicht zu den Ergebnissen führt, die Sie vielleicht erwarten. Im Gegensatz zu einer IF-Anweisung, bei der es darauf ankommt, ob der Ausdruck als wahr oder falsch ausgewertet wird, muss der Ausdruck in einer SWITCH-Anweisung also IMMER als Ergebnis einer Zahl betrachtet werden. Diese Zahl wird dann im nächsten Schritt verwendet.
Im nächsten Schritt kommen die CASE-Anweisungen ins Spiel. An dieser Stelle wird der Ausdruck logisch ausgewertet. Das heißt, er wird als wahr oder falsch ausgewertet. Aber warten Sie einen Moment. Hier scheint es einen Widerspruch zu geben. Haben Sie nicht gerade gesagt, dass der Ausdruck nicht logisch, sondern numerisch ausgewertet wird? Ja, das klingt wie ein Widerspruch. Das ist eine absolut berechtigte Frage, denn auf den ersten Blick ist das alles verwirrend.
Einfacher kann man es leider nicht erklären. Der Wert des Ausdrucks wird nach unten weitergegeben und anhand verschiedener CASE-Anweisungen überprüft. Es gibt keine strikte Reihenfolge. Die Verbindung zwischen dem Ausdruck und den CASE-Werten ist rein numerisch. Bei der Ausführung einer CASE-Anweisung wird der Wert jedoch logisch, d. h. als wahr oder falsch, geprüft. Aus diesem Grund habe ich neben jedem Fall eine zusätzliche Kennzeichnung angebracht: VALUE. Dies veranschaulicht den tatsächlichen Wert, der mit dem Ausdruck verglichen wird. Wenn eine Übereinstimmung vorliegt, wird die entsprechende ROUTINE ausgeführt. Um eine Entscheidung zu treffen, muss ein logischer Vergleich stattfinden, auch wenn er durch eine numerische Übereinstimmung ausgelöst wird. Hier werden die Dinge ein wenig unübersichtlich. Viele Menschen gehen fälschlicherweise davon aus, dass die Auswertung direkt im SWITCH-Ausdruck erfolgt. In Wirklichkeit findet sie jedoch während des Abgleichs eines bestimmten Falles statt.
Habe ich nicht gesagt, dass die SWITCH-Anweisung etwas verwirrend sein kann, wenn man die früheren Artikel nicht ganz verstanden hat? Und wir arbeiten immer noch mit der einfachsten Form davon!
Wie auch immer, sobald CASE überprüft, dass der AUSDRUCK gleich einem WERT (value) ist, wird die entsprechende ROUTINE ausgeführt. Punkt. Neue Zeile. Jetzt kommen wir zu dem Teil, an dem alles kompliziert wird. Aber das wird später erklärt. Dies ist die geheimnisvolle rote Linie, die Sie in Bild 01 gesehen haben. Diese Linie steht für eine tiefere Komplexität, auf die wir jetzt noch nicht eingehen wollen. Ignorieren wir das erst einmal. Wenn Sie nicht selbst erforschen wollen, was passiert, wenn der Fluss durch die rote Linie fließt, schlage ich vor, dass Sie es vorerst dabei belassen. Stattdessen sollten Sie Folgendes tun: Fügen Sie am Ende jedes ROUTINE-Blocks eine BREAK-Anweisung ein. Damit wird sichergestellt, dass die Ausführung den SWITCH-Block sauber verlässt. Diese Aussage macht Spaß, aber sie kann einem wirklich das Gehirn verdrehen, wenn man nicht aufpasst. Es gibt Möglichkeiten, Logik in einen SWITCH zu schreiben, die unglaublich schwer zu verstehen sind, wenn man den Kontrollfluss nicht genau versteht.
Gut, bis jetzt hört sich alles gut an. Aber es gibt einen Gedanken, der mich beunruhigt. In den vorangegangenen Artikeln haben wir gelernt, dass die BREAK-Anweisung es uns ermöglicht, eine Schleife zu verlassen, ohne die Schleifenbedingung neu bewerten zu müssen. Das machte durchaus Sinn. Aber jetzt, wo Sie sehen, dass BREAK in einem SWITCH verwendet wird, sind Sie vielleicht ein wenig verwirrt. Was ist, wenn wir uns in einer Schleife befinden und innerhalb dieser Schleife auch einen SWITCH verwenden, so wie ich es gezeigt haben? Wenn wir BREAK innerhalb des SWITCH verwenden, wird dann nicht die gesamte Schleife vorzeitig abgebrochen? Das ist eine ausgezeichnete Frage, lieber Leser. Diese Art von Fragen zeigt, dass Sie wirklich mitkommen und den bisher behandelten Stoff verstehen. Wir werden also Folgendes tun: Da Sie bereits wissen, wie Sie eine Schleife erstellen und ihren Ablauf mit BREAK, RETURN und CONTINUE steuern können, wollen wir nun ein etwas fortgeschritteneres Beispiel als das zu Beginn dieses Artikels durchgehen,
oder in den früheren. Das Ziel ist es, Klarheit zu schaffen, nicht etwas Besonderes oder Funktionelles zu erstellen, sondern die Konzepte auf praktische, anschauliche Weise darzustellen.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. Print(__FUNCTION__, " ", __LINE__, " Counting..."); 07. Print(__FUNCTION__, " ", __LINE__, " Pit Stop :: ", Tic_Tac()); 08. switch (Tic_Tac()) 09. { 10. case true: 11. Print(__FUNCTION__, " ", __LINE__, " Return TRUE"); 12. break; 13. case false: 14. Print(__FUNCTION__, " ", __LINE__, " Return FALSE"); 15. break; 16. } 17. } 18. //+------------------------------------------------------------------+ 19. bool Tic_Tac(void) 20. { 21. static uchar counter = 10; 22. 23. while (true) 24. { 25. switch (counter) 26. { 27. case 8: 28. counter = counter - 1; 29. return false; 30. case 6: 31. Print("Press TAB to continue or ESC to abort the count."); 32. counter = counter - 1; 33. break; 34. case 5: 35. if (TerminalInfoInteger(TERMINAL_KEYSTATE_TAB)) 36. { 37. Print("Accelerating count."); 38. counter = 2; 39. } else if (TerminalInfoInteger(TERMINAL_KEYSTATE_ESCAPE)) 40. { 41. Print("General panic..."); 42. return false; 43. } 44. continue; 45. case 0: 46. return true; 47. default: 48. counter = counter - 1; 49. } 50. Print(__FUNCTION__, " ", __LINE__, " :: ", counter); 51. Sleep(300); 52. } 53. Print(__FUNCTION__, " ", __LINE__, "This line will never be executed."); 54. } 55. //+------------------------------------------------------------------+
Code 03
In diesem Code 03 werden einige sehr interessante Elemente der Codekonstruktion und -implementierung vorgestellt. Das liegt daran, dass wir hier fast alles verwenden, was wir bis zu diesem Punkt behandelt haben. Bevor wir jedoch in die Details des Code 03 eintauchen, wollen wir uns ansehen, was passiert, wenn er im MetaTrader 5 Terminal ausgeführt wird. Tatsächlich gibt es zwei mögliche Ergebnisse, die in den folgenden Animationen gezeigt werden.
Animation 01
In dieser ersten Animation können Sie sehen, was passiert, wenn die ESC-Taste gedrückt wird. Wenn wir nun die TAB-Taste drücken, geschieht etwas anderes, wie in der nächsten Animation gezeigt wird.
Animation 02
Beachten Sie, dass es einen kleinen Unterschied zwischen den beiden Animationen gibt. Es kommt jedoch darauf an, zu verstehen, wie diese Informationen das Terminal erreichen - und wie die Ablaufsteuerungsanweisungen bestimmen, wann die einzelnen Informationen erscheinen.
Nun, liebe Leserinnen und Leser, ich werde hier nicht in allen Einzelheiten auf bestimmte Teile eingehen. Ich möchte Sie nämlich dazu ermutigen, die vorherigen Artikel noch einmal zu lesen, um wirklich zu verstehen, wie die einzelnen Flusssteuerungsanweisungen funktionieren. Ich werde dennoch einen Überblick über die Entwicklung von Code 03 geben.
Beginnen wir mit dem Einstiegspunkt des Codes, der OnStart heißt. Zeile 6 zeigt, wo wir uns im Ausführungsprozess befinden. Diese Zeile wird gedruckt, sobald sie ausgeführt wird. Die Zeile 7 wird jedoch nicht sofort bearbeitet. Denn er enthält einen Aufruf der Funktion Tic_Tac. Infolgedessen wird die vollständige Ausführung von Zeile 7 verschoben, bis Tic_Tac seine Aufgaben erledigt hat.
In der Funktion Tic_Tac (Zeile 19) geraten wir in Zeile 23 in eine Endlosschleife. Aber keine Sorge, lieber Leser, diese Schleife ist in ihrer Form unendlich, aber wir haben bestimmte Punkte, an denen sie verlassen werden kann. Schauen Sie genau hin, um zu verstehen, was hier passiert. In Zeile 25 geben wir die Anweisung SWITCH zur Ablaufsteuerung ein. Für jeden relevanten Zählerwert führen wir eine bestimmte Aktion durch. Beachten Sie, dass die Zählervariable als statisch deklariert ist. Das ist sehr wichtig. Wenn der Zähler den Wert acht erreicht, kehren wir zum Aufrufer zurück und geben den Wert false zurück. Zu diesem Zeitpunkt ist die Zeile 7 vollständig ausgeführt. Dies erklärt die Meldung, die auf dem Terminal erscheint. Danach gehen wir zu Zeile 8 und rufen die Funktion Tic_Tac erneut auf. Aber dieses Mal verwenden wir den Rückgabewert als Ausdruck in einer anderen SWITCH-Anweisung. Auch hier wartet die Ausführung, bis Tic_Tac abgeschlossen ist. Wir kehren also zu Zeile 19 zurück und fahren von dort aus fort.
Warten Sie. Sind wir nicht bei Zeile 29 ausgestiegen? Sie fragen sich vielleicht: Wenn wir in Zeile 29 aufhören würden, würde das nicht alles zurücksetzen und die Schleife in Zeile 23 wieder in Zeile 29 enden lassen? Das würde es, lieber Leser. Da aber Zeile 28 vor der Rückkehr zum Aufrufer ausgeführt wurde, verweisen wir jetzt auf den Wert sieben. Und da es keinen passenden Fall für den Wert sieben im SWITCH in Zeile 25 gibt, springt die Ausführung zu Zeile 47. Zeile 47 enthält eine Routine, die nur die Zeile 48 ausführt, die den Zähler um eins verringert. Jetzt zeigt der Zähler den Wert sechs an.
Wie auch immer, nach Abschluss des SWITCH-Blocks fahren wir mit den Zeilen 50 und 51 fort. Aus diesem Grund erscheinen bestimmte Werte, wie z. B. sieben, nicht im Terminal. Sobald der Wert sechs gedruckt ist, beginnt die Schleife von neuem, und die SWITCH-Anweisung wird erneut ausgeführt. Jetzt hat der Ausdruck den Wert sechs. Und jetzt aufgepasst. In Zeile 31 geben wir eine weitere Nachricht auf dem Terminal aus. Dann, in Zeile 32, setzen wir den Zähler auf fünf. Aber was passiert in Zeile 33, wo eine BREAK-Anweisung verwendet wird? Dies ist der Punkt, an dem viele Anfänger verwirrt sind. Aus früheren Artikeln wissen wir, dass BREAK die Schleife, in der es sich befindet, beendet. Das stimmt, und das wurde eindeutig bewiesen. In diesem speziellen Fall wird die äußere Schleife durch die Unterbrechung jedoch nicht beendet. Das liegt daran, dass sie hier Teil der SWITCH-Anweisung ist. In diesen Situationen gilt BREAK für den SWITCH, nicht für die ihn umgebende Schleife, egal ob es sich um WHILE, DO WHILE oder FOR handelt.
Das mag verwirrend erscheinen, aber um dieses Verhalten zu beweisen, habe ich eine Meldung in Zeile 53 eingefügt - eine Meldung, die in diesem Code 03 NIE gedruckt wird. Auch wenn das einzige BREAK im gesamten Code in Zeile 33 steht.
Ich denke, das sollte klar sein. Dieser Code ist an den Artikel angehängt, sodass Sie ihn in Ruhe studieren können, bis diese kleine Eigenheit bei der Verwendung des BREAK-Operators klar wird.
Sobald das BREAK in Zeile 33 ausgeführt wurde, gehen wir direkt zu Zeile 50 über. Denken Sie daran, dass der Zähler in Zeile 32 verringert wurde. Er hat jetzt also den Wert fünf.
Die Schleife läuft erneut, und der SWITCH wird erneut überprüft. Dieses Mal ergibt der Ausdruck den Wert fünf. Da wir einen CASE für diesen Wert haben, wird er ausgeführt. Und genau hier wird es interessant. Auch hier sollten Sie genau aufpassen. An diesem Punkt wartet das Programm darauf, dass der Nutzer eine der Tasten drückt, die in der Meldung erwähnt werden, die angezeigt wird, wenn der Zähler sechs war. Aber (und das ist der entscheidende Punkt), wenn der Nutzer keine Taste drückt, führt Zeile 44 eine CONTINUE-Anweisung aus. Nun stellt sich die Frage. Da sich CONTINUE immer auf die umschließende Schleife bezieht, springt die Ausführung zurück zu Zeile 23. Dadurch werden die Zeilen 50 und 51 vollständig übersprungen. Dies gilt so lange, wie der Ausdruck den Wert fünf ergibt. Sobald der Nutzer eine Taste drückt, ändert sich der Ablauf erneut. Je nach gedrückter Taste gehen wir entweder zu Zeile 38, wo der Zähler auf zwei gesetzt wird, oder zu Zeile 42. Wie auch immer, irgendwann, entweder in Zeile 42 oder 46, endet die Schleife. Aber auch dann wird die Zeile 53 nie ausgeführt. Wir kehren dann zu Zeile 8 zurück. An dieser Stelle wird der neue Ausdruck ausgewertet. Aber jetzt fragen Sie sich vielleicht: „Warte. Sollte switch nicht Ausdrücke numerisch auswerten? Warum sind die Werte von case jetzt boolesche Werte? Das ergibt für mich keinen Sinn.“ Und genau das, lieber Leser, ist der Punkt. Als wir die IF-Anweisung besprochen haben, habe ich erklärt, was einen Wert wahr oder falsch macht. Der Begriff „falsch“ bleibt unverändert. Wenn es jedoch um die Wahrheit geht, verschieben sich die Dinge ein wenig. In diesem Fall ist der Wert TRUE in Zeile 10 tatsächlich der numerische Wert 1. Wenn also die Funktion Tic_Tac entweder 0 oder 1 zurückgibt, erkennt der SWITCH in Zeile 8 dies und es wird eine entsprechende Meldung angezeigt. Wenn Sie jedoch den Rückgabewert von Tic_Tac auf etwas anderes als 0 oder 1 ändern, findet der SWITCH in Zeile 8 keinen passenden Fall. Und es wird keine Meldung angezeigt.
Es ist wichtig, eines zu beachten. Wenn Sie statt der SWITCH-Anweisung in Zeile 8 eine IF-Anweisung verwenden würden, könnte eine Meldung angezeigt werden. Dies hängt davon ab, wie Sie IF implementieren. Und genau das ist das Ziel: Sie sollen wie ein Programmierer denken können. Ich werde Ihnen nicht genau sagen, was Sie tun sollen. Stattdessen möchte ich, dass Sie wie ein Programmierer denken und versuchen zu verstehen, wie jede Anweisung funktioniert, einschließlich ihrer Möglichkeiten und Grenzen.
Abschließende Überlegungen
In diesem Artikel haben wir uns mit der Funktionsweise der SWITCH-Anweisung befasst. Ich verstehe, dass dies auf den ersten Blick mehr Verwirrung stiftet als es löst. Aber ich versichere Ihnen, dass es Ihnen nach einiger Übung sehr nützlich sein wird. Ich möchte es noch einmal betonen: Studieren Sie jede Kontrollstruktur langsam. Versuchen Sie, das gleiche Verhalten auf etwas andere Weise zu wiederholen. Dies wird Ihnen helfen, ein besseres Verständnis dafür zu entwickeln, wie alles zusammenpasst.
Fangen Sie klein an, überstürzen Sie nicht gleich die Erstellung eines Indikators oder Expert Advisors. Bauen Sie zunächst eine solide Wissensgrundlage auf. Auf diese Weise werden Ihre Entwicklungsbemühungen effizienter und Ihre harte Arbeit wird besser belohnt. Nehmen Sie sich also Zeit, sehen Sie sich den beigefügten Code an, und wir sehen uns im nächsten Artikel wieder.
Übersetzt aus dem Portugiesischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/pt/articles/15391





- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.