Ответы здесь кажутся очень сложными (но точными, тем не менее.) Итак, вот мои мысли.
Во-первых, мне нравится dmckee (рабочее) определение FSM и как они применяются к программированию.
конечный автомат состоит из конечного числа дискретных состояний (я знаю, педантичным, но до сих пор), который может как правило, быть представлен в виде целых значений . В c или C++ с использованием перечисления очень распространено перечисление.
Машина реагирует на конечное число входов, которые часто могут быть , представленного с другим числом значной переменной. В более сложных случаях вы можете использовать структуру для , представляя состояние ввода.
Каждая комбинация внутреннего состояния и внешний вход заставит машину к:
- возможно переход в другое состояние
- возможно генерировать некоторый вывод
Итак, вы программа. Он имеет состояния, и их конечное число. («лампочка яркая» или «лампочка тусклая» или «лампочка выключена». 3 состояния конечны.) Ваша программа может быть только в одном состоянии за раз.
Итак, скажите, что вы хотите, чтобы ваша программа меняла состояния. Обычно вам нужно что-то произойти, чтобы вызвать изменение состояния. В этом примере, как насчет ввода пользовательского ввода для определения состояния - скажем, нажатия клавиши.
Возможно, вам понадобится такая логика. Когда пользователь нажимает клавишу:
- Если лампа выключена, сделайте лампу «тусклой».
- Если лампа «тускнеет», сделайте лампу «яркой».
- Если лампа «яркая», сделайте лампу «выключено».
Очевидно, вместо того, чтобы «менять лампу», вы можете «менять цвет текста» или что бы то ни было, что вам нужно выполнить программе. Прежде чем начать, вы захотите определить свои состояния.
Так, глядя на код 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;
}
}
И, вуаля. Простая программа, которая изменяет состояние.
Этот код выполняет лишь небольшую часть инструкции switch
- в зависимости от состояния . Затем это обновления, что состояние. Вот как работают FSM.
Теперь вот некоторые вещи, которые вы можете сделать:
Очевидно, что эта программа просто изменяет переменную currentState
. Вы хотите, чтобы ваш код делал что-то более интересное при изменении состояния. Функция doCoolBulbStuff()
может, я не знаю, на самом деле поставить изображение лампочки на экране. Или что-то.
Этот код ищет только нажатия клавиши. Но ваш FSM (и, следовательно, ваш оператор switch) может выбирать состояние, основанное на том, что вводил пользователь (например, «O» означает «перейти в выключенное состояние», а не просто идти к тому, что будет дальше в последовательности.)
Часть вашего вопроса требует структуры данных.
Один человек предложил использовать enum
для отслеживания состояний. Это хорошая альтернатива #defines
, которую я использовал в моем примере. Люди также предлагали массивы - и эти массивы отслеживают переходы между государствами. Это также тонкая структура для использования.
Учитывая вышеизложенное, вы можете использовать любую структуру (что-то древовидное, массив, что угодно), чтобы отслеживать отдельные состояния и определять, что делать в каждом состоянии (следовательно, некоторые из предложений использовать «указатели функций» - иметь карту состояний для указателя функции, который указывает, что делать в этом состоянии.)
Надеюсь, что это поможет!
Возможно, вас заинтересует Ragel (http://www.complang.org/ragel/), который является компилятором конечного автомата, который может генерировать код C. Если это не соответствует вашим целям, возможно, сгенерированный код представляет интерес. – sris
related http://stackoverflow.com/questions/1647631/c-state-machine-design/1651187 – jldupont