[分享] C語言 FSM 實做心得 (以 csv 拆解為例)

看板C_and_CPP (C/C++)作者 (藍影)時間15年前 (2010/12/30 01:22), 編輯推噓3(3017)
留言20則, 5人參與, 最新討論串1/1
東西不要欠過年 - 上次關於讀 csv 用 FSM 實做的文章 (#1D3f8CHP) 要先自爆一件事, 裡面的觀念雖然沒什麼大錯, 不過裡面的 FSM 圖表全都錯。 這二天花了點時間再去 studying FSM 的東西 (其實說明真的不多), 大致上就是要有 CurrentState、Condition、Action(Function)、NextState 組成, 其它的東西我想大家都有一定熟悉度, 於此便不贅述, 先附上我最後成功 FSM 用的圖 http://ppt.cc/H1dm 說實在話, 我還真沒看過標準 FSM 是怎麼畫的, (有參考網址的話請不吝分享) 所以這裡舉個例子說明我的 FSM 圖怎麼看 ┌─────┐ ┌────────┐ │ ptr++ │ *ptr!='"' │des[c][j] = *ptr│ │ TexT │ ───────> │j++, ptr++ │ └─────┘ │ T2 │ ^ └────────┘ | | |________________________________| 1. 在進入 Text 狀態時,會先執行 ptr++; 2. 若狀態為 TexT 且 *ptr!= '"',則會先做 des[c][j] = *ptr, j++, ptr++; 做完後再轉到狀態 T2 3. 正常而言 T2 狀態應該要有一個 condition 才會轉到 Text, 可是第一次畫不懂, 所以 T2 到 Text 是必然結果, 屬 "無條件轉換"。 最後建立表格後會長得像這樣 http://ppt.cc/;V7E 實際實做 FSM 後,我總算體會到 goto 的發明是為了什麼.. 初版原始碼 http://codepad.org/9d3VP28g 用 goto 的做法優點是非常快就可以寫完,但缺點是不易維護,於是又 try 了第二種方式 在說第二種方式前又要自爆一件事,上面的那個圖表,只要是屬於 "無條件轉換" 的 都要先把它給化簡掉 (其實也不知道為什麼, 實做發現化簡掉實做比較不會出問題,不化簡就一直做不出來) 化簡之後的 FSM 表在這 http://ppt.cc/ozPv (瞬間從 S9 降到 S5) 接著又用 C 語言實做 http://codepad.org/QCPmcBYI 這個我承認真的是醜到不行, struct 定義方面我都嫌它很麻煩了, 我也還在想到底是還有什麼技巧沒用到, 這部份倒是該請教各位版友的地方。 另也知道 FSM 可以包成 Class, 這樣應該可以避免上面用void *param 這種難堪的局面。 最後結束前, 事實上 FSM 用 C/C++/JAVA 實做, 已經有軟體在支援, 免費的在這裡 http://www.nunnisoft.ch/nunnifsmgen/en/ 應是 open source, 我跑了一次發現我竟然不會改裡面產生的 pattern, 有興趣的話可以前往參考 最後可以的話, 請版主 #1D3f8CHP 把這篇的 m 拿掉 (砍掉可能會好些), 不然留錯的東西給別人看也尷尬 以上, 感謝收聽。 -- YouLoveMe() ? LetItBe() : LetMeFree(); -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.76.142 ※ 編輯: tropical72 來自: 180.177.76.142 (12/30 01:30)

12/30 01:31, , 1F
@_@
12/30 01:31, 1F
※ 編輯: tropical72 來自: 180.177.76.142 (12/30 01:38)

12/30 03:47, , 2F
我覺得你的寫法很怪, 應該要用一個變數 state 來判別
12/30 03:47, 2F

12/30 03:51, , 3F
目前的狀態, 像 http://0rz.tw/2yOLk 這樣吧
12/30 03:51, 3F

12/30 07:02, , 4F
報告 t 大, 典型教科書是使用圓圈代表 state, 例如:
12/30 07:02, 4F

12/30 07:03, , 5F
http://tinyurl.com/2ud8onb 不過啟始狀態跟結束狀態的
12/30 07:03, 5F

12/30 07:04, , 6F
圖示都略有不同. 如果真的要"標準"的話, UML 有定義.
12/30 07:04, 6F

12/30 07:05, , 7F
可以用 Google Images 找 UML state diagram 就有.
12/30 07:05, 7F

12/30 07:08, , 8F
另外, 誠如k大所言, 典型的FSM實作方法是使用while(TRUE)
12/30 07:08, 8F

12/30 07:09, , 9F
加 switch case 做成, 簡化說明版: codepad.org/HrndF6xQ
12/30 07:09, 9F

12/30 07:11, , 10F
FSM裡的每個圓圈跟箭頭都可以很漂亮的套用進來 :-)
12/30 07:11, 10F

12/30 16:54, , 11F
謝謝 k 大與 i 大建議,這部份我再補起來.感謝.
12/30 16:54, 11F

12/30 18:50, , 12F
我是覺得nunni產生的code還蠻漂亮的
12/30 18:50, 12F

12/30 18:51, , 13F
不過可惜沒有GUI的前端可以配合
12/30 18:51, 13F

12/30 18:53, , 14F
他那四欄是 目前狀態 遇到的事件 下個狀態 要做的動作
12/30 18:53, 14F

12/30 18:56, , 15F
以Dog來說,Dog.c裡面都是 "要做的動作"
12/30 18:56, 15F

12/30 18:57, , 16F
Run.c則是在教如何執行(實際可以做的只有餵事件給他)
12/30 18:57, 16F

12/30 18:58, , 17F
你可以把它想成黑盒子 "事件"是輸入 "要做的動作"是輸出
12/30 18:58, 17F

12/30 19:00, , 18F
至於甚麼狀態遇到甚麼事件會跳到甚麼狀態則是黑箱
12/30 19:00, 18F

12/30 19:00, , 19F
這黑箱是由狀態表來產生的
12/30 19:00, 19F

12/30 19:38, , 20F
我花些時間再仔細研究 numi 怎麼用好了,謝謝 b 大
12/30 19:38, 20F
文章代碼(AID): #1D6svFd5 (C_and_CPP)
文章代碼(AID): #1D6svFd5 (C_and_CPP)