程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> 用C語言實現有限狀態自動機FSM

用C語言實現有限狀態自動機FSM

編輯:關於C
摘要:狀態機模式是一種行為模式,在《設計模式》這本書中對其有詳細的描述,通過多態實現不同狀態的調轉行為的確是一種很好的方法,只可惜在嵌入式環境下,有時只能寫純C代碼,並且還需要考慮代碼的重入和多任務請求跳轉等情形,因此實現起來著實需要一番考慮。本文主要為你實現一個簡單的有限狀態機,沒有考慮代碼的重入和多任務跳轉,為以後復雜的狀態機實現,打下基礎。    本文來源:用C語言實現有限狀態自動機FSM       一、狀態機實現的要素   首先,分析一下一個普通的狀態機究竟要實現哪些內容。   狀態機存儲從開始時刻到現在的變化,並根據當前輸入,決定下一個狀態。這意味著,狀態機要存儲狀態、獲得輸入(我們把它叫做跳轉條件)、做出響應。       如上圖所示,{s1, s2, s3}均為狀態,箭頭c1/a1表示在s1狀態、輸入為c1時,跳轉到s2,並進行a1操作。   最下方為一組輸入,狀態機應做出如下反應:   當前狀態 輸入 下一個狀態 動作 s1 c1 s2 a1 s2 c2 s3 a2 s3 c1 s2 a3 s2 c2 s3 a2 s3 c1 s2 a3 s2 c1 s_trap a_trap s_trap c1 s_trap a_trap     當某個狀態遇到不能識別的輸入時,就默認進入陷阱狀態,在陷阱狀態中,不論遇到怎樣的輸入都不能跳出。   為了表達上面這個自動機,我們定義它們的狀態和輸入類型:     typedef int state; typedef int condition;   #define  STATES 4 #define  STATE1 0 #define  STATE2 1 #define  STATE3 2 #define  STATETRAP 3   #define  CONDITIONS 2 #define  CONDITION1 0 #define  CONDITION2 1  總結一下,我們需要定義的有狀態、輸入、行為(動作+下一個狀態),其中,行為的個數是“狀態數*輸入數量”(其中有一些是重復的);其中動作一般來說可以用一個函數指針來實現。     二、具體設計          在嵌入式環境中,由於存儲空間比較小,因此把它們全部定義成宏。此外,為了降低執行時間的不確定性,我們使用O(1)的跳轉表來模擬狀態的跳轉。   首先定義跳轉類型:     typedef void (*actiontype)(state  mystate, condition condition);   typedef struct {     state  next;     actiontype  action; }  trasition, * ptrasition;     然後按照上圖中的跳轉關系,把三個跳轉加一個陷阱跳轉先定義出來:     //  (s1, c1, s2, a1) trasition  t1 = {     STATE2,     action1 };   //  (s2, c2, s3, a2) trasition  t2 = {     STATE3,     action2 };   //  (s3, c1, s2, a3) trasition  t3 = {     STATE2,     action3 };   //  (s, c, trap, a1) trasition  tt = {     STATETRAP,     actiontrap };     其中的動作,由用戶自己完成,在這裡僅定義一條輸出語句。   1 2 3 4 void action1(State  state, Condition condition) {     printf("Action  1 triggered.\n"); } 1 最後定義跳轉表:    asition  transition_table[STATES][CONDITIONS] = { /*       c1,  c2*/ /*  s1 */&t1,  &tt, /*  s2 */&tt,  &t2, /*  s3 */&t3,  &tt, /*  st */&tt,  &tt, };     即可表達上文中的跳轉關系。   最後定義狀態機,如果不考慮多任務請求,那麼狀態機僅需要存儲當前狀態便行了。例如:     typedef struct {     State  current; }  StateMachine, * pStateMachine;   State  step(pStateMachine machine, Condition condition) {     pTrasition  t = transition_table[machine->current][condition];     (*(t->action))(machine->current,  condition);     machine->current  = t->next;     return machine->current; }   總結:我們現在設計實現好了一個狀態機,然後要給這個狀態機特定的輸入,看看狀態機的運轉情況,以上面圖中的那個狀態機為例,我們輸入的序列是0和1分別代表c1和C2,然後狀態s1,s2分別對應0,1.用程序實現這個內容如下   三、程序實現   程序清單:小型狀態機的實現 [cpp  #include<stdio.h>   #include<unistd.h>   #include<stdlib.h>   typedef int state;   typedef int condition;      #define STATENUM 4   #define STATE1 0   #define STATE2 1   #define STATE3 2   #define STATETRAP 3      #define CONDITIONS 2   #define CONDITION1 0   #define CONDITION2 1      typedef void (* actiontype)(state mystate,condition mycondition);   typedef struct{     state next;     actiontype action;   }trasition, *ptrasition;      void action1(state mystate,condition myconditon);   void action2(state mystate,condition myconditon);   void action3(state mystate,condition myconditon);   void actiontrap(state mystate,condition myconditon);   trasition t1={     STATE2,action1   };   trasition t2={     STATE3,action2   };   trasition t3={     STATE2,action3   };   trasition tt={     STATETRAP,actiontrap   };      void action1(state mystate,condition myconditon){     printf("action1 one triggered\n");   }   void action2(state mystate,condition myconditon){     printf("action2 one triggered\n");   }   void action3(state mystate,condition myconditon){     printf("action3 one triggered\n");   }   void actiontrap(state mystate,condition myconditon){     printf("actiontrap one triggered\n");   }      ptrasition transition_table[STATENUM][CONDITIONS] = {   /*      c1,  c2*/   /* s1 */&t1, &tt,   /* s2 */&tt, &t2,   /* s3 */&t3, &tt,   /* st */&tt, &tt,   };   typedef struct   {       state current;   } StateMachine, * pStateMachine;       state step(pStateMachine machine, condition mycondition)   {       ptrasition t = transition_table[machine->current][mycondition];       (*(t->action))(machine->current, mycondition);       machine->current = t->next;       printf("the current state is %d\n",t->next );       return machine->current;   }   int main(int argc, char *argv[])   {     StateMachine mymachine;     mymachine.current=STATE1;     int mycon;     char ch;     while(1){       scanf("%d",&mycon);        step(&mymachine,mycon);     }     return 0;   }    
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved