78 votes

tutoriels sur les machines d'état

Je me demande simplement si quelqu'un connaît de bons didacticiels sur Internet pour développer des machines d'état. Ou des ebooks?

Je commence à travailler sur des machines d'état et j'ai juste besoin de quelque chose de général pour bien démarrer.

145voto

qrdl Points 17813

Les machines d'état sont très simples en C si vous utilisez des pointeurs de fonction.

En principe, vous avez besoin de deux tableaux: un pour les pointeurs de fonction d'état et un pour les règles de transition d'état. Chaque fonction state renvoie le code, vous consultez la table de transition d'état par état et vous retournez le code pour rechercher l'état suivant, puis simplement l'exécuter.

 int entry_state(void);
int foo_state(void);
int bar_state(void);
int exit_state(void);

/* array and enum below must be in sync! */
int (* state[])(void) = { entry_state, foo_state, bar_state, exit_state};
enum state_codes { entry, foo, bar, end};

enum ret_codes { ok, fail, repeat};
struct transition {
    enum state_codes src_state;
    enum ret_codes   ret_code;
    enum state_codes dst_state;
};
/* transitions from end state aren't needed */
struct transition state_transitions[] = {
    {entry, ok,     foo},
    {entry, fail,   end},
    {foo,   ok,     bar},
    {foo,   fail,   end},
    {foo,   repeat, foo},
    {bar,   ok,     end},
    {bar,   fail,   end},
    {bar,   repeat, foo}};

#define EXIT_STATE end
#define ENTRY_STATE entry

int main(int argc, char *argv[]) {
    enum state_codes cur_state = ENTRY_STATE;
    enum ret_codes rc;
    int (* state_fun)(void);

    for (;;) {
        state_fun = state[cur_state];
        rc = state_fun();
        if (EXIT_STATE == cur_state)
            break;
        cur_state = lookup_transitions(cur_state, rc);
    }

    return EXIT_SUCCESS;
}
 

Je ne mets pas la fonction lookup_transition() car elle est triviale.

C'est comme ça que je fais des machines à états depuis des années.

30voto

Christoph Points 64389

Je préfère utiliser les pointeurs de fonction que les énormes déclarations switch , mais contrairement à la réponse de qrdl, je n'utilise normalement pas de codes de retour explicites ni de tables de transition.

En outre, dans la plupart des cas, vous aurez besoin d’un mécanisme permettant de transmettre des données supplémentaires. Voici un exemple de machine d'état:

 #include <stdio.h>

struct state;
typedef void state_fn(struct state *);

struct state
{
    state_fn * next;
    int i; // data
};

state_fn foo, bar;

void foo(struct state * state)
{
    printf("%s %i\n", __func__, ++state->i);
    state->next = bar;
}

void bar(struct state * state)
{
    printf("%s %i\n", __func__, ++state->i);
    state->next = state->i < 10 ? foo : 0;
}

int main(void)
{
    struct state state = { foo, 0 };
    while(state.next) state.next(&state);
}
 

8voto

X-Istence Points 7179

Les machines d'état ne sont pas quelque chose qui, naturellement, a besoin d'un tutoriel pour expliquer ou même utilisé. Ce que je suggère, c'est que vous prenez un regard sur les données et la manière dont elle doit être analysée.

Par exemple, j'ai eu à analyser les données, le protocole pour l'un Près de l'Espace de vol en montgolfière ordinateur, c'données stockées sur la carte SD dans un format spécifique (binaire), qui doit être analysé dans une séparation par virgule fichier. À l'aide d'une machine d'état pour ce qui fait le plus de sens car en fonction de ce que le bit suivant de l'information est que nous devons changer ce que nous sommes de l'analyse.

Le code est écrit en C++, et est disponible en ParseFCU. Comme vous pouvez le voir, il détecte tout d'abord quelle version nous sommes de l'analyse, et à partir de là elle entre deux machines d'état.

Il entre dans la machine d'état dans un bon état, à ce moment nous commençons l'analyse et en fonction de ce que les personnages que nous rencontrons nous, soit de passer à l'état suivant, ou revenir à un état précédent. En fait cela permet au code d'auto-adapter à la façon dont les données sont stockées et si oui ou non certaines données existent à tous les même.

Dans mon exemple, le GPS de la chaîne n'est pas une exigence pour le vol de l'ordinateur pour se connecter, et le traitement de la GPS chaîne peut être ignorée si la fin octets pour cette seule écriture de journal est trouvé.

État des machines sont simples à écrire, et, en général, j'ai suivi la règle qu'il doit circuler. D'entrée en passant par le système devrait circuler avec une certaine facilité d'état à état.

4voto

Roman Khimov Points 21

Il y a beaucoup de leçons à apprendre à la fabrication manuelle de machines à états en C, mais permettez-moi également de suggérer le compilateur de machines à états Ragel:

http://www.complang.org/ragel/

Il a un moyen assez simple de définir des machines d'état et ensuite vous pouvez générer des graphiques, générer du code dans différents styles (piloté par des tables, piloté par goto), analyser ce code si vous le souhaitez, etc. Et c'est puissant, il peut être utilisé en production code pour divers protocoles.

4voto

ChrisW Points 37322

La modélisation en temps réel orientée objet était fantastique (publiée en 1994 et vendue pour seulement 81 cents, plus 3,99 $ frais d'expédition).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X