Las respuestas aquí parecen realmente complejas (pero precisas, no obstante.) Así que aquí están mis pensamientos.
Primero, me gusta la definición (operativa) de dmckee de un FSM y cómo se aplican a la programación.
Una máquina de estado finito se compone de un número discreto finito de estados (I sé pedante, pero todavía), que puede generalmente ser representado como un número entero valores. En c o C++ usando una enumeración es muy común.
La máquina responde a una finito número de entradas que puede a menudo ser representados con otra variable valorada número entero . En los casos más complicados puede utilizar una estructura para representar el estado de entrada.
Cada combinación de estado interno y entrada externa hará que la máquina a:
- posiblemente transición a otro estado
- posiblemente generar alguna salida
para que tenga una programa. Tiene estados, y hay un número finito de ellos. ("la bombilla es brillante" o "la bombilla está apagada" o "la bombilla está apagada". 3 indica "finito"). Su programa solo puede estar en un estado a la vez.
Por lo tanto, supongamos que quiere que su programa cambie de estado. Por lo general, querrá que algo al pase para activar un cambio de estado. En este ejemplo, qué tal si tomamos la entrada del usuario para determinar el estado, por ejemplo, presionando una tecla.
Es posible que desee una lógica como esta. Cuando el usuario presiona una tecla:
- Si la bombilla está "apagada", haga que la bombilla se "atenúe".
- Si la bombilla está "tenue", haga que la bombilla sea "brillante".
- Si la bombilla está "brillante", apague la bombilla.
Obviamente, en lugar de "sustituir una lámpara", es posible que "cambiar el color del texto" o lo que sea que el programa tiene que hacer. Antes de comenzar, querrá definir sus estados.
Así que buscando en algún código pseudoish C:
/* We have 3 states. We can use constants to represent those states */
#define BULB_OFF 0
#define BULB_DIM 1
#define BULB_BRIGHT 2
/* And now we set the default state */
int currentState = BULB_OFF;
/* now we want to wait for the user's input. While we're waiting, we are "idle" */
while(1) {
waitForUserKeystroke(); /* Waiting for something to happen... */
/* Okay, the user has pressed a key. Now for our state machine */
switch(currentState) {
case BULB_OFF:
currentState = BULB_DIM;
break;
case BULB_DIM:
currentState = BULB_BRIGHT;
doCoolBulbStuff();
break;
case BULB_BRIGHT:
currentState = BULB_OFF;
break;
}
}
Y, voila. Un programa simple que cambia el estado.
Este código ejecuta solo una pequeña parte de la instrucción switch
, según el estado actual. Entonces actualiza ese estado. Así es como funcionan los FSM.
Ahora aquí hay algunas cosas que puede hacer:
Obviamente, este programa sólo cambia la variable currentState
. Querrá que su código haga algo más interesante en un cambio de estado. La función doCoolBulbStuff()
podría, no sé, poner realmente una imagen de una bombilla en una pantalla. O algo.
Este código solo busca una pulsación de tecla. Pero su FSM (y por lo tanto su declaración de cambio) puede elegir estado en función de lo que ingresó el usuario (por ejemplo, "O" significa "ir a apagado" en lugar de simplemente ir a lo que sea siguiente en la secuencia.)
Parte de su pregunta pidió una estructura de datos.
Una persona sugirió usar un enum
para realizar un seguimiento de los estados. Esta es una buena alternativa al #defines
que utilicé en mi ejemplo. La gente también ha estado sugiriendo matrices, y estas matrices llevan un registro de las transiciones entre estados. Esta es también una buena estructura para usar.
Dado lo anterior, bien, podría usar cualquier tipo de estructura (algo similar a un árbol, una matriz, cualquier cosa) para realizar un seguimiento de los estados individuales y definir qué hacer en cada estado (de ahí algunas sugerencias para utilice "punteros a funciones": tenga un mapa de estado con un puntero a función que indique qué hacer en ese estado)
Espero que ayude!
Puede que le interese Ragel (http://www.complang.org/ragel/) que es un compilador de máquina de estados que puede generar código C. Si no cumple sus propósitos, tal vez el código generado sea de interés. – sris
relacionado http://stackoverflow.com/questions/1647631/c-state-machine-design/1651187 – jldupont