日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用C语言实现有限状态自动机FSM

發布時間:2025/3/21 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用C语言实现有限状态自动机FSM 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

摘要:狀態機模式是一種行為模式,在《設計模式》這本書中對其有詳細的描述,通過多態實現不同狀態的調轉行為的確是一種很好的方法,只可惜在嵌入式環境下,有時只能寫純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

?

當某個狀態遇到不能識別的輸入時,就默認進入陷阱狀態,在陷阱狀態中,不論遇到怎樣的輸入都不能跳出。

為了表達上面這個自動機,我們定義它們的狀態和輸入類型:

1 2 3 4 5 6 7 8 9 10 11 12 typedef?int?s tate; typedef?int?c ondition; #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)的跳轉表來模擬狀態的跳轉。

首先定義跳轉類型:

1 2 3 4 5 6 7 typedef?void? (*actiontype)(state mystate, condition condition); typedef?struct { ????state next; ????actiontype action; } trasition, * ptrasition;

?

然后按照上圖中的跳轉關系,把三個跳轉加一個陷阱跳轉先定義出來:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // (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 最后定義跳轉表:
1 2 3 4 5 6 7 ptrasition transition_table[STATES][CONDITIONS] = { /*????? c1,? c2*/ /* s1 */ &t1, &tt, /* s2 */ &tt, &t2, /* s3 */ &t3, &tt, /* st */ &tt, &tt, };

?

即可表達上文中的跳轉關系。

最后定義狀態機,如果不考慮多任務請求,那么狀態機僅需要存儲當前狀態便行了。例如:

1 2 3 4 5 6 7 8 9 10 11 12 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.用程序實現這個內容如下

三、程序實現


程序清單:小型狀態機的實現 #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 1typedef 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】 嵌入式設計模式:有限狀態自動機的C語言實現? http://www.cnblogs.com/autosar/archive/2012/06/22/2558604.html

總結

以上是生活随笔為你收集整理的用C语言实现有限状态自动机FSM的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。