C / C++ Switch case Sprünge von case zu case

#3684856
Lesenswert?

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
#3684882
Lesenswert?

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.
Gast #3684901
Lesenswert?

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.
#3684950
Lesenswert?

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.
#3684969
Lesenswert?

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...
#3685024
Lesenswert?

@ 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
Gast #3685031
Lesenswert?

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.
#3685048
Lesenswert?

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.
#3685051
Lesenswert?

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...
#3685065
Lesenswert?

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
#3685090
Lesenswert?

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.
#3685096
Lesenswert?

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.
#3685349
Lesenswert?

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.
#3685358
Lesenswert?

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?
Gast #3685426
Lesenswert?

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.
#3685442
Lesenswert?

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 ;-)
(Firma: Brainit GmbH) #3686837
Lesenswert?

@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...)
Gast #3686890
Lesenswert?

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.
#3687670
Lesenswert?

@ 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
#3687757
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren