Gast
#1303956
Hallo! Wie realisiert man am besten einen Zustandsautomat mit dem GCC? Einfach über eine Zustandsvariablen und switch() Anweisungen oder gibts da bessere Wege, oder gar Compilerunterstützung? MFG
|
Anzeige
|
Zustandsautomat mit avr-gcc
Gast
#1303956
Hallo! Wie realisiert man am besten einen Zustandsautomat mit dem GCC? Einfach über eine Zustandsvariablen und switch() Anweisungen oder gibts da bessere Wege, oder gar Compilerunterstützung? MFG
Gast
#1304010
Variable+switch ist ok. Wenn du C++ verwendest und es bissl komplizierter magst, dann kannst du das auch über Objekte machen. (state design pattern) Frank schrieb: > Wie realisiert man am besten einen Zustandsautomat mit dem GCC? Einfach > über eine Zustandsvariablen und switch() Anweisungen oder gibts da > bessere Wege, oder gar Compilerunterstützung? Es gibt Beschreibungssprachen für Zustandsautomaten (state machines) und Compiler aus diesen Sprachen nach C, C++,... http://freshmeat.net/search?q=state+machine&submit=Search
Gast
#1304493
Vielleicht noch ein kleiner Tipp: Bevor du jetzt zum softwaretechnischen Rundumschlag ausholst, denk bitte daran: KISS - keep it simple stupid Das soll heißen, wenn du dein Problem einfach mit einer Zustandsvariable und einem switch lösen kannst, dann mach es auch so. Du solltest aber dann nicht die gesamte Funktionalität in der switch-Anweisung ausprogrammieren. Also ich halte sowas hier für sinnvoll:
Ich hab schon Sourcecode gesehen, da hat einer das gesamte Programm in einen switch Block gepackt, der dann weit über 2000 Zeilen lang war. Da sieht niemand mehr durch. Er hatte dann auch keine Lust gehabt, neue Zustände einzuführen und hat dann die Funktion rekursiv mit irgendwelchen Nebenbedingungen aufgerufen.
Gast
#1305085
>Er hatte dann auch keine Lust gehabt, neue >Zustände einzuführen und hat dann die Funktion rekursiv mit >irgendwelchen Nebenbedingungen aufgerufen. In diese Versuchung kam ich auch schon, erschien mir einfacher und übersichtlicher eben weil kein zusätzlicher state. Also werd ich nach dem KISS arbeiten ariable+switch ... schrieb:
>
Naja, das ist doch für Anfänger ganz praktikabel. Aber als Steigerung kannst Du es gleich so machen: // Zustandvariable ist ein Funktionszeiger void (*state)(void); // Zustand einstellen state = state_abc; // Zustand ausführen: state();
Gast
#1305200
Zeiger auf Funktion kenn ich on Callbacks, aber welchen Vorteil hat das hier? Man muss ja trotzdem den aktuellen State abfragen. Ob ich verschiednene Funktionen aufrufe, oder der state() Funktion eine Addresse zuweise und ausführe ändert ja nichts. Oder doch?
Gast
#1305233
@Frank Abfrage erübrigt sich bei Funktionszeigern, die Funktion ist mit dem Status identisch. Skua schrieb: > @Frank > > Abfrage erübrigt sich bei Funktionszeigern, die Funktion ist mit dem > Status identisch. Kannst du das konkretisieren, zB in C? Ich wüsste jetzt nicht, wie ich einen Funktionszeiger-Typ definieren könnte für Funktionen, die Funktionen dieses Typs zurückliefern. Konkret als Skelett mal folgender C-Code:
Hier muss doch wieder eine Status-Variable eingeführt werden. Schaffst du es ohne eine solche Variable? Wie sieht dann der Typedef für statehandler_t aus, ohne daß man Schweinereien wie Pointer-Casts braucht oder über globale Variablen (bäh) kommuniziert? Du willst also sowas stattdessen:
Preisfrage: Wie sieht der Typedef für state_t aus? Johann
Gast
#1305412
> ...ohne daß man Schweinereien wie Pointer-Casts braucht > oder über globale Variablen (bäh) kommuniziert? Dein Code enthält doch auch eine globale Variable. Aber wie wär's damit (vielleicht noch mit geschickterer Namensgebung):
Rolf Magnus schrieb: >> ...ohne daß man Schweinereien wie Pointer-Casts braucht >> oder über globale Variablen (bäh) kommuniziert? > > Dein Code enthält doch auch eine globale Variable. > Aber wie wär's damit (vielleicht noch mit geschickterer Namensgebung): > >
Den Status hatte ich ganz bewusst aus "welt" rausgehalten, weil er da konzeptionell nicht hingehört. Die Statemaschine operiert auf einem Objekt, sie ist nicht darin verwoben. Mit folgendem Code kann man vielleicht sowas erreichen, aber wirklich verständlich ist das auch nicht gerade und irgendwie grenzwertig:
Leider gibt es in der gekennzeichneten Zeile noch eine Warnung. Das ganze ist eher ne Spielerei, um rauszufinden ob sowas geht in C. In Haskell oder so ist das bestimmt easy... Der Code ist aber immerhin korrekt trotz der Warnung:
Johann Johann L. schrieb: > typedef struct state_t > { > struct state_t * (*(*state) (struct welt_t*))(struct welt_t*); > } state_t; Ui. Das ist aber hart :-) Ich habs auch noch nie geschafft. Ein typedef für einen Funktionspointer, der einen Funktionspointer auf denselben Typ zurückgibt, ist eines der grossen Mysterien in C. PS: Ich würds gar nicht so kompliziert machen. Einfach einen globalen Funktionspointer und jeder State hat das Recht einen anderen State dort einzutragen. Beim Kopieren verloren gegangen:
Johann Karl heinz Buchegger schrieb: > Johann L. schrieb: > >> typedef struct state_t >> { >> struct state_t * (*(*state) (struct welt_t*))(struct welt_t*); >> } state_t; > > Ui. > Das ist aber hart :-) > > Ich habs auch noch nie geschafft. Ein typedef für einen > Funktionspointer, der einen Funktionspointer auf denselben Typ > zurückgibt, ist eines der grossen Mysterien in C. > > PS: Ich würds gar nicht so kompliziert machen. > Einfach einen globalen Funktionspointer und jeder State hat das Recht > einen anderen State dort einzutragen. Ist wie gesagt um die Grenzen auszuloten und zu testen, ob sowas überhaupt geht. In meinen Programmen würd ich sowas net hinschreiben. Was noch stört ist die Struktur, aber wie man die wegbekommen kann, da hab ich echt keine Idee. Und in Standard-C (also nicht in GNU-C) gibt das bestimmt Fehler. Man kann natürlich eine Funktion definieren, die als Rückgabewert (oder auch als Partameter) Funktionszeiger hat, aber die sind dann von einem anderen Typ. Auch eine Implementierung von slartibartfas, die nichts am State ändert, liefert eine Warning.
Im Endeffekt passieren an den Stellen, wo gewarnt wird, Pointer-Casts, die man ja nicht haben will (zumindest wenn man sauber programmiert). Johann
Gast
#1305600
ja, wirklich beeindruckend wie man einen einfachen übersichtlichen switch so programmieren kann, dass man gar nichts mehr versteht. Ich hoffe, dass das beim philosophieren bleibt, sonst erschiene es mir etwas masochistisch. l.g. gebhard
Gast
#1305699
> Den Status hatte ich ganz bewusst aus "welt" rausgehalten, weil er > da konzeptionell nicht hingehört. Du wolltest ja keine separate globale Variable. Notfalls kann man auch eine Struktur nochmal außenrum machen, so daß welt ein Teil davon ist und der Status ein anderer. > Die Statemaschine operiert auf einem Objekt, sie ist nicht darin > verwoben Das Objekt hat aber einen Zustand. Deshalb sehe ich kein Problem darin, diesen im Objekt zu speichern. Das hängt aber davon ab, ob die Statemachine das Objekt zur Laufzeit wechseln soll und dabei aber ihren Zustand beibehalten muß. In der Regel würde ich davon ausgehen, daß das nicht der Fall ist. Mir gefällt es irgendwie nicht, daß deine Zustandsfunktionen jeweils einen neuen Zustand als Returnwert zurückgeben. Da finde ich das Speichern im Objekt schöner. Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|