Hej leute hab da mal ne kurze frage. Ist es unter C / C++ möglich wie in der Programmierung von SPS Systemen unter der (Programmiersprache structured text in der codesys umgebung) Sprünge in der Switchcase zu machen? Z.B. in structured text kann ich sagen: case 10: if bla bla then 20: case 20: if bla bla then 30: case 30: if bla bla then 10: So kann ich von case 10 nach 20 nach 30 und wieder nach 10. Gibt es einen Befehl wie man bei C / C++ von case zu case springen kann?? Danke im voraus. LG
Hallo, das geht nicht mit C/C++. Warscheinlich ist switch/case nicht das richtige Konstrukt um deine Daten auszuwerten. Was willst du denn genau machen? Grüße,
Shabi N. schrieb: > Gibt es einen Befehl wie man bei C / C++ von case zu case springen > kann?? Ja, einfach das break weglassen, dann läuft man in den nächsten Case. Ist aber nicht MISRA.
:
Bearbeitet durch User
Hallo, es gibt das GOTO in ANSI-C, http://www.programiz.com/c-programming/c-goto-statement und auch in C++ http://msdn.microsoft.com/de-de/library/b34dt9cd.aspx aber muss das sein?
1 | int a = 10; |
2 | int cont = 0; |
3 | do { |
4 | switch (a) { |
5 | case 10: |
6 | ...
|
7 | break
|
8 | case 20: |
9 | ...
|
10 | if (...) a = 30; |
11 | if (endebedingung) cont = 0; |
12 | break
|
13 | case 30: |
14 | ...
|
15 | if (...) a = 10; |
16 | break
|
17 | }
|
18 | } while (cont); |
Ist ein Zustandsautomat.
:
Bearbeitet durch User
Also mein haupt Vorhaben (Endziel) ist es einen mini SPS mit einem Microcontroller wie z.b. atmega 328... nach zu bauen. Ich kann halt nur C/c++ und strutured Text. Wenn es natürlich eine Umgebung gibt mit der man µC mit strutured Text programmieren kann, wäre es auch eine Option. LG
Shabi N. schrieb: > Wenn es natürlich eine Umgebung gibt mit der man µC mit strutured Text > programmieren kann, ??? Ich dachte du kannst c/c++: Shabi N. schrieb: > Ich kann halt nur C/c++ und strutured Text. Also programmiere den µC in c! Shabi N. schrieb: > Also mein haupt Vorhaben (Endziel) ist es einen mini SPS mit einem > Microcontroller wie z.b. atmega 328... nach zu bauen. Eine SPS selbst bauen? Inclusive einem Compiler oder Interpreter? So ganz verstehe ich es noch nicht.
:
Bearbeitet durch User
Wenn du in jedem case nur eine Funktion aufrufst und ein break hast, hast du erstens saubereren Code und zweitens kannst du ja aus einer Methode eine andere aufrufen. Man muss nicht ein ganzes Programm in eine einzige Methode oder gar in ein switch/case quetschen.
@UDO Nein der µC dient nur als Steuerung wie zb eine SPS Steuerung... Die Steuerung wird dann Regler ansteuern die wiederum Motoren ansteuern. Es werden auch einige Sensoren wie zb Lichtschranken an die Steuerung angeschlossen aber das ist erstmal nebensache...
:
Bearbeitet durch User
Klingt stark nach einer Zustandsmaschine, oder? Gruß Dennis
> Ich kann halt nur C/c++ und strutured Text.
Sehr schön. Dann programmier Dir einen Interpreter für structured Text
in C oder C++, der auf dem µC der Wahl läuft. Das war jetzt einfach.
Technisch sehe ich da kein Problem. Die Syntax sagt:
1 | statement: |
2 | labeled-statement |
3 | … |
4 | |
5 | labeled-statement: |
6 | identifier ':' statement |
7 | 'case' constant-expression ':' statement |
8 | 'default' ':' statement |
Es spricht (syntaktisch) also nichts dagegen, zwei labels hintereinander zu setzen, von denen eines per switch, das andere per goto angesprungen wird, also etwa:
1 | switch ( … ) { |
2 | case 10: |
3 | label_10:
|
4 | …
|
5 | goto label_10; |
6 | }
|
Ich habe's nicht probiert, sollte aber gehen. Ob das sinnvoll ist steht natürlich auf einem anderen Blatt. Wie hier schon gesagt wurde deutet einiges darauf hin, dass das Design sich verbessern lässt.
Man kann durchaus wilde Sachen mit einem switch() machen - s. z.B. hier: http://de.wikipedia.org/wiki/Duff%E2%80%99s_Device - oder so was:
1 | {
|
2 | int bed = 0; |
3 | |
4 | switch (bed) |
5 | {
|
6 | case 0: |
7 | l0:
|
8 | printf("case 0, bed = %d\n", bed); |
9 | goto l1; |
10 | |
11 | case 1: |
12 | l1:
|
13 | printf("case 1, bed = %d\n", bed); |
14 | goto l3; |
15 | break; |
16 | |
17 | |
18 | case 2: |
19 | l2:
|
20 | printf("case 2, bed = %d\n", bed); |
21 | break; |
22 | |
23 | case 3: |
24 | l3:
|
25 | printf("case 3, bed = %d\n", bed); |
26 | goto l2; |
27 | }
|
28 | }
|
wild zwischen den case labels rumspringen. Bloß versteht's dann keiner mehr...
@ Markus F Ja soetwas hab ich gesucht. Ich kenne den Befehl GOTO aber dachte immer das ein GOTO absolut Tabu ist und man keine Programm Sprünge damit machen sollte. Weiß jetzt natürlich nicht ob es in einem Switch case anders ist... Danke schonmal an alle werde mal ein paar tests machen... LG
Shabi N. schrieb: > @ Markus F > Ja soetwas hab ich gesucht. Au weia, da hab' ich dir was gezeigt. Ich bin absolut sicher, das goto-Rumgehüpfe ist nicht die richtige Lösung für dein Problem. Am besten beschreibst Du einfach mal, was dein Problem überhaupt ist?
Shabi N. schrieb: > Ja soetwas hab ich gesucht. Ich kenne den Befehl GOTO aber dachte immer > das ein GOTO absolut Tabu ist und man keine Programm Sprünge damit > machen sollte. Kommt drauf an. GOTO wird in der Kernel- und Treiberprogrammierung verwendet, um efizienten Code zu schreiben. Aber in einem switch-case mit einem goto wild zwischen den cases hin und her zu springen ist unsauber, schlecht und auch ueberhaupt nicht sinn und zweck von switch-case/goto. Entweder du benutzt switch-case oder goto, aber nicht beides zusammen.
Markus F. schrieb: > Am besten beschreibst Du einfach mal, was dein Problem überhaupt ist? Wahrscheinlich einen unsauberen Zustandsautomat völlig zu verhunzen :-( Na ja der TO schaufelt seinem Programm damit langfristig das Grab. Warnungen gabs genug.
Markus F. schrieb: > Shabi N. schrieb: >> @ Markus F >> Ja soetwas hab ich gesucht. > > Au weia, da hab' ich dir was gezeigt. Das war aber abzusehen. Sorry, aber das musste auch mal gesagt werden. Einem Anfänger sowas zu zeigen ist fahrlässig.
Kaj schrieb: > Shabi N. schrieb: >> Ja soetwas hab ich gesucht. Ich kenne den Befehl GOTO aber dachte immer >> das ein GOTO absolut Tabu ist und man keine Programm Sprünge damit >> machen sollte. > Kommt drauf an. > GOTO wird in der Kernel- und Treiberprogrammierung verwendet, um > efizienten Code zu schreiben. Und vor allen Dingen wird das von Programmierern gemacht, die wissen was sie tun und die das was sie da tun auch unter Kontrolle halten können. Ich habe nicht den Eindruck, dass der TO in diese Kategorie fällt.
:
Bearbeitet durch User
Karl Heinz schrieb: > > Das war aber abzusehen. > Sorry, aber das musste auch mal gesagt werden. Einem Anfänger sowas zu > zeigen ist fahrlässig. Wahrscheinlich hätten wir's noch drei oder vier Minuten geheimhalten können, dann hätt' er's bei Google gefunden ;) C ist nun mal eine Sprache, mit der man sich elegant in den eigenen Fuß schießen kann. Wer's richtig lernen will, muß das wohl hin und wieder machen...
Also Leute damit hier keine Missverständnisse entstehen. Ich will weder etwas verhunzen noch eine Sprache Unsauber nutzen. Meine ursprüngliche Frage war ja nur ob es einen Befehl gibt um switch case in C wie in strutured Text nutzen zu können. Das Projekt ist noch in der Brain storming Phase und es ist noch nichts passiert... Wenn alle stricke reißen nutze ich einen Raspbarry und werde mich hiernach orientieren. http://www.sps-forum.de/beckhoff-codesys-iec61131/68431-codesys-auf-dem-raspberry-pi-jetzt-verfuegbar.html @ UDO nicht immer gleich vom schlimmsten ausgehen nur weil einer eine Frage stellt :-) Lange Rede kurzer Sinn wenn ich es richtig verstanden habe kann man in C sowas wie in structured text nicht realisieren. Somit bleibt mir doch noch die Möglichkeit Funktionen zu nutzen. Und dazu nur eine Frage: Ist es ok zwischen Funktionen hin und her zu springen oder ist das unsauber und nicht im sinne des erfinders? LG
Shabi N. schrieb: > Und dazu nur eine Frage: > Ist es ok zwischen Funktionen hin und her zu springen oder ist das > unsauber und nicht im sinne des erfinders? Das ist nicht im Sinne des Erfinders. Sobald du 'herumspringen' benutzt, solltest du dir überlegen, ob du nicht einen groben Designfehler hast. Ja, es gibt Fälle, in denen ein goto bzw. ein ähnlicher Mechanismus die sauberste Lösung darstellt. Aber diese Fälle sind rar gesät und in den nächsten paar Jahren wirst du nicht in die Verlegenheit kommen, so etwas benutzen zu müssen. Bis dahin gilt: wenn du versucht bist einen goto zu benutzen, dann ist dein Design schlecht und du solltest lieber an deinem Design arbeiten. Ich bin jetzt 30 Jahre im Geschäft (davon 20 Jahre C++) und in all den Jahren hab ich ein einziges mal einen goto gebraucht. Und selbst den haben wir Jahre später zugunsten einer besseren Lösung ausgebaut.
:
Bearbeitet durch User
Shabi N. schrieb: > Also mein haupt Vorhaben (Endziel) ist es einen mini SPS mit einem > Microcontroller ... Dafür brauchst du das von dir angestrebte Gefrickel nicht (und auch kein C++). man Zustandsautomat Um auf eine Frage zu kommen: Ja, diese Möglichkeit gibt es, nennt sich "GOTO" und ist wildestes Gefrickel. Roland
Shabi N. schrieb: > @ UDO > nicht immer gleich vom schlimmsten ausgehen nur weil einer eine Frage > stellt :-) Ich habe dir oben einen Beispielcode für einen einfachen Zustandsautomaten gepostet, das Stichwort "Zustandsautomat" wurde mehrfach erwähnt, du darfst es gerne weiter ignorieren. :-) Bzgl vom Schlimmsten ausgehen: Ich habe dein Beispiel gesehen, das ist schon schlimm, und wenn solche Krebsgeschwüre in einem Programm wachsen, dann kommt irgendwann etwas raus was man nur noch wegwerfen kann. Jahrzehntelange Erfahrung lehrt: Am besten so schnell wie möglich wegwerfen.
:
Bearbeitet durch User
Karl Heinz schrieb: > Markus F. schrieb: >> Shabi N. schrieb: >>> @ Markus F >>> Ja soetwas hab ich gesucht. >> >> Au weia, da hab' ich dir was gezeigt. > > Das war aber abzusehen. > Sorry, aber das musste auch mal gesagt werden. Einem Anfänger sowas zu > zeigen ist fahrlässig. Viel mehr würden mich einige andere Dinge stören: Ein goto ist überflüssig (obwohl man es der Lesbarkeit halber akzeptieren und hoffen kann, dass der Compiler es wegoptimiert), ein break ist definitiv zu viel und könnte sogar zu einem statement not reachable oder ähnlichem Fehler führen, und das es sich beim ersten Zeichen der Label um eine kleines L und nicht die Ziffer 1 handelt, was den entscheidenden Unterschied zwischen einem Identifier und eine numerischen Konstante ausmacht, ist bei dem verwendeten Font für den Anfänger auch nicht unbedingt einfach zu erkennen. Abgesehen davon halte ich die kontextlose Verteufelung des goto für nicht weniger fahrlässig. Das Ergebnis sind dann solche Auswüchse, wie wir oben gesehen haben. Sorry Udo (urschmitt), aber bei solchem Code sträuben sich bei mir die Nackenhaare. Was spricht dagegen, das ganz natürlich und sauber mit goto zu lösen?:
1 | void fsm() |
2 | {
|
3 | state_10:
|
4 | ...
|
5 | goto state_10; // Endlosschleife ? |
6 | |
7 | state_20:
|
8 | ...
|
9 | if ( endebedingung ) return; // Reihenfolge getauscht, da nur eine Anweisung |
10 | if ( ... ) goto state_30; // der beiden einen Effekt haben kann und diese |
11 | // Reihenfolge dem zu erwartenden Effekt entspricht
|
12 | state_30:
|
13 | ...
|
14 | if ( ... ) goto state_10; |
15 | }
|
Der Code ist strukturell identisch, kürzer, nicht schlechter lesbar, eher im Gegenteil macht er einige mögliche Fehler offensichtlicher (siehe Kommentare), kommt ohne zwei überflüssige Variablen, eine überflüssige Schleife und ein überflüssiges switch aus, der Compiler wird meckern, wenn ein nicht vorhandener Zustand angesprungen werden sollte und obendrein ist der Code auch noch effizienter. Die immer noch weit verbreitete goto-Phobie stammt noch aus einer Zeit, in der die meisten Programmierer mit Basic oder Assembler begonnen haben, in Sprachen also, in denen das goto oft die einzige Möglichkeit der Verzweigung war, und die dann dieses gewohnte und leider auch sehr flexible Sprachmittel als Universalwerkzeug kritiklos auf alle passenden und unpassenden Situationen übertrugen, auch dann, wenn andere Sprachen besser Alternativen boten. Damals dürfte sie daher sogar berechtigt gewesen sein. Diese Zeiten sind aber lange vorbei. Neuere Lehrbücher erwähnen goto wenn überhaupt dann nur noch am Rande. Der TO ist das beste Beispiel, der goto ja offenbar noch nicht einmal kannte. Die Gefahr des Missbrauchs würde ich daher heute als deutlich geringer einschätzen Andererseits verbaut man sich mit dem Verzicht aber Möglichkeit, siehe das Beispiel von Udo. Das goto ist zunächst ein Sprachmittel wie jedes andere auch, es kann gebraucht und missbraucht werden, es kann adäquat sein oder nicht, aber nicht gut oder schlecht per se. Was adäquat bedeutet hängt vom zu Grunde liegenden Modell ab und für einen nicht ereignisgetriebenen endlichen Automaten, der abhängig von Zustand und Input eine Aktion ausführen und dann zum nächsten Zustand gehen soll (go to next state), gibt es meine bescheidenen Meinung nach kein adäquateres Sprachmittel als das goto. Alles andere führt zu unnötigem Overhead, zusätzlicher Komplexität, schlechterer Lesbarkeit, höherer Fehleranfälligkeit und schlechteren Prüfmöglichkeiten für den Compiler. Also mal etwas mehr Mut zum goto! Das man wissen muss was man tut, gilt natürlich immer noch, aber das gilt immer und woher soll ein Anfänger es lernen, wenn wir es ihm nicht zeigen. After all: 'There never has been nor ever will be a programming language, where it is at least a bit difficult to write bad code!' PS: Die häufige Verwendung von goto in vielen Treibern und anderen Kernelkomponenten halte ich übrigens für keine adäquate Anwendung. Ich habe noch keine Situation erlebt, die man mit strukturierten Mitteln nicht genauso gut oder besser hätte lösen können.
:
Bearbeitet durch User
A. H. schrieb: > as Ergebnis sind dann solche Auswüchse, wie > wir oben gesehen haben. Sorry Udo (urschmitt), aber bei solchem Code > sträuben sich bei mir die Nackenhaare. Na was genau sträubt denn deine Nackenhaare? :-) Die Zeilen habe ich schnell zusammengetippt, falls also ein Semikolon fehlt... Statt hier seitenweise einen Vortrag zu halten zeige wie man es besser macht. [ ] Du weisst was ein Zustandsautomat ist?
@ Karl Heinz Danke für deine Tipps im Grunde hast du ja recht mit dem Designe überprüfung.... @ UDO Ich den Zustandsautomat nicht ignoriert. Was soll ich denn noch dazu sagen. (Siehe Digitaltechnik 1. Semester...) Allen anderen danke ich vielmals für eure Tipps. LG
Mal eine ganz andere Frage: Wozu mußt du in deinem Zustandsautomat wild zwischen den Zuständen hin und her springen? Die Variable, die du in dem zu den cases gehörenden switch abfragst, enthält den Zustand (der übrigens nicht über "magic numbers", sondern über Namen zu identifizieren sein sollte). Wenn du den Zustand ändern willst, weist du den der Variablen zu, und das nächste mal, wenn der Automat aufgerufen wird (also das switch ausgeführt wird), passiert ganz von selbst der Sprung an die richtige Stelle. Wozu sollte man da mitten aus einem Zustand heraus direkt in einen anderen rüberspringen wollen? Shabi N. schrieb: > Z.B. in structured text kann ich sagen: > > case 10: > if bla bla > then 20: > > case 20: > if bla bla > then 30: > > case 30: > if bla bla > then 10: > > So kann ich von case 10 nach 20 nach 30 und wieder nach 10. Und wann kommt er dann zum Switch? Das sieht mir nach einer Endlosschleife aus, in der ich mir die Zustände auch gleich sparen kann.
Udo Schmitt schrieb: > Statt hier seitenweise einen Vortrag zu halten zeige wie man es besser > macht. Nanu, hast Du Deinen eigenen Code nicht mehr erkannt? Das Beispiel oben habe ich 1:1 von Dir abgeschrieben, lediglich jedes case Label durch ein goto Label ersetzt, jedes a= durch eine goto Anweisung (was ja letztlich nichts anderes ist als eine Zuweisung an den Befehlszähler) und dann alles weggestrichen, was überflüssig geworden war. Wobei ich gerade feststelle, dass mir da ein Fehler unterlaufen ist: Ich hätte auch jedes break ersetzen müssen, nicht nur das erste. Hier also die korrigierte Variante:
1 | void fsm() |
2 | {
|
3 | state_10:
|
4 | ...
|
5 | goto state_10; // Endlosschleife ? |
6 | |
7 | state_20:
|
8 | ...
|
9 | if ( endebedingung ) return; // Reihenfolge getauscht, da nur eine Anweisung |
10 | if ( ... ) goto state_30; // der beiden einen Effekt haben kann und diese |
11 | goto state_20; // Reihenfolge dem zu erwartenden Effekt entspricht |
12 | |
13 | state_30:
|
14 | ...
|
15 | if ( ... ) goto state_10; |
16 | goto state_30; |
17 | }
|
> [ ] Du weisst was ein Zustandsautomat ist?
Ich hoffe, sonst würde ich mir hier keine Meinung erlauben ;-)
:
Bearbeitet durch User
@ah8, danke für deinen "Vortrag"! Deine Ausführungen zum sinnvollen Einsatz von GOTO sprechen mir absolut aus der Seele! Und das Beispiel mit dem kleinen Zustandsautomaten passt wunderbar! (meint der Michi, der Goto ganz ganz selten verwendet, dann aber mit (sehr) gutem gewissen, und der das allgemeine GOTO-bashing nicht leiden kann, und der außerdem den Essay "real programmers don't use pascal" liebt...)
Shabi N. schrieb: > Ich kann halt nur > C/c++ Das bezweifle ich. > und strutured Text. Das bezweifle ich ebenfalls, sonst würdest du den Namen nicht falsch schreiben. Wie wäre denn ein C-Buch?
kopfkratz Also entweder Du willst einen Interpreter realisieren oder nur "rumtrollen", was ist es ? Du kannst entweder wie schon gesagt einen Zustandsautomaten mit passenden Übergängen realisieren oder einen echten Interpreter. Bei einem Interpreter solltest Du Dir mal grundlegendes Wissen über BNF&Co. ansehen und auch verstehen. Wenn Du dann weißt wie man Token erkennt und entsprechend auswertet kannst Du eine SPS mit Deinem Code kontrollieren. Die Frage ist halt mal wieder was wirklich geplant ist und was wirklich benötigt wird ? Eine gute Übung wäre z.B. wenn Du jetzt einfach mal hingehst und Dir einen BNF Interpreter baust der eine Textdatei mit der BNF Deiner Programmersprache lesen und interpretieren kann. Wenn Du soweit bist kannst Du sicherlich eine SPS realisieren.
@ Progger Danke für deine Verurteilung... Hab halt nen Tippfehler gemacht der sich durch copy and paste nach unten geschlichen hat. @ Kopfkratzer Im Grunde ist es eine Maschine die mehrere Achsen und Sensoren hat die je nach Code/ Programm bewegt/ausgewertet werden. Die abläufen sind immer die selben. ZB. -Maschine an -Referenzfahr aller achsen -Maschine starten -Maschinenablauf -Maschine Stoppen ... Um alles zu erklären müsste ich viel zu weit ausholen. Den Tipp mit dem BNF find ich super. Werde bei Zeiten mal rein schauen und mich mit befassen. Hab aktuell noch einige andere Projekte die abgeschlossen werden müssen... Um das ganze jetzt zusammen zu fassen: Mit C/C++ wäre es zwar möglich aber ist unsauber und nicht im sinne des erfinders. Ich denke ich werde dann eine andere Lösung suchen wie die von oben mit nem Raspbarry. Da kann man auch in der CODESYS Umgebung programmieren. Danke an alle. LG
Shabi N. schrieb: > Um das ganze jetzt zusammen zu fassen: > Mit C/C++ wäre es zwar möglich aber ist unsauber und nicht im sinne des > erfinders. Also, zu behaupten dass sich so etwas in C/C++ nicht sauber implementieren lässt wäre nun der völlig falsche Schluss. Das Problem ist, dass Du zwei Sprachmittel miteinander kombinieren möchtest, die unterschiedlichen Ansätzen folgen, nämlich das switch und das goto. Die Wahl der Sprachmittel wird durch das zu Grunde liegendes Modell bestimmt und Dein Versuch legt den Verdacht nahe, dass Du Dir über diese Modell noch nicht hinreichend im Klaren bist. Sollte das stimmen so wäre es Dein Design, dass unsauber ist, nicht aber das Problem und auch die Sprache.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.