偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

函數(shù)指針?lè)椒▽?shí)現(xiàn)簡(jiǎn)單狀態(tài)機(jī)(附代碼)

開(kāi)發(fā) 后端
之前寫(xiě)過(guò)一篇狀態(tài)機(jī)的實(shí)用文章,很多朋友說(shuō)有幾個(gè)地方有點(diǎn)難度不易理解,今天給大家換種簡(jiǎn)單寫(xiě)法,使用函數(shù)指針的方法實(shí)現(xiàn)狀態(tài)機(jī)。

之前寫(xiě)過(guò)一篇狀態(tài)機(jī)的實(shí)用文章,很多朋友說(shuō)有幾個(gè)地方有點(diǎn)難度不易理解,今天給大家換種簡(jiǎn)單寫(xiě)法,使用函數(shù)指針的方法實(shí)現(xiàn)狀態(tài)機(jī)。

狀態(tài)機(jī)簡(jiǎn)介

有限狀態(tài)機(jī)FSM是有限個(gè)狀態(tài)及在這些狀態(tài)之間的轉(zhuǎn)移和動(dòng)作等行為的數(shù)學(xué)模型,是一種邏輯單元內(nèi)部的高效編程方法,可以根據(jù)不同狀態(tài)或者消息類型進(jìn)行相應(yīng)的處理邏輯,使得程序邏輯清晰易懂。

函數(shù)指針實(shí)現(xiàn)FSM

使用函數(shù)指針實(shí)現(xiàn)FSM可以分為3個(gè)步驟

  1. 建立相應(yīng)的狀態(tài)表和動(dòng)作查詢表
  2. 根據(jù)狀態(tài)表、事件、動(dòng)作表定位相應(yīng)的動(dòng)作處理函數(shù)
  3. 執(zhí)行完成后再進(jìn)行狀態(tài)的切換

代碼實(shí)現(xiàn)步驟

1.定義狀態(tài)數(shù)據(jù)的枚舉類型 

  1. typedef enum { 
  2.   state_1=1, 
  3.   state_2, 
  4.   state_3, 
  5.   state_4 
  6. }State; 

2.定義事件的枚舉類型 

  1. typedef enum{ 
  2.   event_1=1, 
  3.   event_2, 
  4.   event_3, 
  5.   event_4, 
  6.   event_5 
  7. }EventID; 

3.定義狀態(tài)表的數(shù)據(jù)類型 

  1. typedef struct 
  2.     int event;   //事件 
  3.     int CurState;  //當(dāng)前狀態(tài) 
  4.     void (*eventActFun)();  //函數(shù)指針 
  5.     int NextState;  //下一個(gè)狀態(tài) 
  6. }StateTable; 

4.定義處理函數(shù)及建立狀態(tài)表 

  1. void f121() 
  2.     printf("this is f121\n"); 
  3. void f221() 
  4.     printf("this is f221\n"); 
  5. void f321() 
  6.     printf("this is f321\n"); 
  7.  
  8. void f122() 
  9.     printf("this is f122\n"); 
  10.  
  11. StateTable fTable[] = 
  12.     //{到來(lái)的事件,當(dāng)前的狀態(tài),將要要執(zhí)行的函數(shù),下一個(gè)狀態(tài)} 
  13.     { event_1,  state_1,    f121,  event_2 }, 
  14.     { event_2,  state_2,    f221,  event_3 }, 
  15.     { event_3,  state_3,    f321,  event_4 }, 
  16.     { event_4,  state_4,    f122,  event_1 }, 
  17.     //add your code here 
  18. }; 

5.狀態(tài)機(jī)類型,及狀態(tài)機(jī)接口函數(shù)

  1. /*狀態(tài)機(jī)類型*/ 
  2. typedef struct { 
  3.     int curState;//當(dāng)前狀態(tài) 
  4.     StateTable * stateTable;//狀態(tài)表 
  5.     int size;//表的項(xiàng)數(shù) 
  6. }fsmType; 
  7.  
  8. /*狀態(tài)機(jī)注冊(cè),給它一個(gè)狀態(tài)表*/ 
  9. void fsmRegist(fsmType* pFsm, StateTable* pTable) 
  10.     pFsm->stateTable = pTable; 
  11.  
  12. /*狀態(tài)遷移*/ 
  13. void fsmStateTransfer(fsmType* pFsm, int state) 
  14.     pFsm->curState = state; 
  15.  
  16. /*事件處理*/ 
  17. void fsmEventHandle(fsmType* pFsm, int event) 
  18.     StateTable* pActTable = pFsm->stateTable; 
  19.     void (*eventActFun)() = NULL;  //函數(shù)指針初始化為空 
  20.     int NextState; 
  21.     int CurState = pFsm->curState; 
  22.     int maxNum = pFsm->size
  23.     int flag = 0; //標(biāo)識(shí)是否滿足條件 
  24.  
  25.     /*獲取當(dāng)前動(dòng)作函數(shù)*/ 
  26.     for (int i = 0; i<maxNum; i++) 
  27.     { 
  28.         //當(dāng)且僅當(dāng)當(dāng)前狀態(tài)下來(lái)個(gè)指定的事件,我才執(zhí)行它 
  29.         if (event == pActTable[i].event && CurState == pActTable[i].CurState) 
  30.         { 
  31.             flag = 1; 
  32.             eventActFun = pActTable[i].eventActFun; 
  33.             NextState = pActTable[i].NextState; 
  34.             break; 
  35.         } 
  36.     } 
  37.  
  38.  
  39.     if (flag) //如果滿足條件了 
  40.     { 
  41.         /*動(dòng)作執(zhí)行*/ 
  42.         if (eventActFun) 
  43.         { 
  44.             eventActFun(); 
  45.         } 
  46.  
  47.         //跳轉(zhuǎn)到下一個(gè)狀態(tài) 
  48.         fsmStateTransfer(pFsm, NextState); 
  49.     } 
  50.     else 
  51.     { 
  52.         printf("there is no match\n"); 
  53.     } 

 

附代碼

代碼直接復(fù)制過(guò)去就行啦,本想打包的,太麻煩了。

測(cè)試程序

  1. //編譯器:http://www.dooccn.com/cpp/ 
  2. //來(lái)源:技術(shù)讓夢(mèng)想更偉大 
  3. //作者:李肖遙 
  4. #include <stdio.h> 
  5.  
  6. typedef enum { 
  7.   state_1=1, 
  8.   state_2, 
  9.   state_3, 
  10.   state_4 
  11. }State; 
  12.  
  13. typedef enum{ 
  14.   event_1=1, 
  15.   event_2, 
  16.   event_3, 
  17.   event_4, 
  18.   event_5 
  19. }EventID; 
  20.  
  21. typedef struct { 
  22.     int event;   //事件 
  23.     int CurState;  //當(dāng)前狀態(tài) 
  24.     void (*eventActFun)();  //函數(shù)指針 
  25.     int NextState;  //下一個(gè)狀態(tài) 
  26. }StateTable; 
  27.  
  28. void f121() 
  29.     printf("this is f121\n"); 
  30. void f221() 
  31.     printf("this is f221\n"); 
  32. void f321() 
  33.     printf("this is f321\n"); 
  34.  
  35. void f122() 
  36.     printf("this is f122\n"); 
  37.  
  38. StateTable fTable[] = 
  39.     //{到來(lái)的事件,當(dāng)前的狀態(tài),將要要執(zhí)行的函數(shù),下一個(gè)狀態(tài)} 
  40.     { event_1,  state_1,    f121,  event_2 }, 
  41.     { event_2,  state_2,    f221,  event_3 }, 
  42.     { event_3,  state_3,    f321,  event_4 }, 
  43.     { event_4,  state_4,    f122,  event_1 }, 
  44.     //add your code here 
  45. }; 
  46.  
  47. /*狀態(tài)機(jī)類型*/ 
  48. typedef struct { 
  49.     int curState;//當(dāng)前狀態(tài) 
  50.     StateTable * stateTable;//狀態(tài)表 
  51.     int size;//表的項(xiàng)數(shù) 
  52. }fsmType; 
  53.  
  54. /*狀態(tài)機(jī)注冊(cè),給它一個(gè)狀態(tài)表*/ 
  55. void fsmRegist(fsmType* pFsm, StateTable* pTable) 
  56.     pFsm->stateTable = pTable; 
  57.  
  58. /*狀態(tài)遷移*/ 
  59. void fsmStateTransfer(fsmType* pFsm, int state) 
  60.     pFsm->curState = state; 
  61.  
  62. /*事件處理*/ 
  63. void fsmEventHandle(fsmType* pFsm, int event) 
  64.     StateTable* pActTable = pFsm->stateTable; 
  65.     void (*eventActFun)() = NULL;  //函數(shù)指針初始化為空 
  66.     int NextState; 
  67.     int CurState = pFsm->curState; 
  68.     int maxNum = pFsm->size
  69.     int flag = 0; //標(biāo)識(shí)是否滿足條件 
  70.  
  71.     /*獲取當(dāng)前動(dòng)作函數(shù)*/ 
  72.     for (int i = 0; i<maxNum; i++) 
  73.     { 
  74.         //當(dāng)且僅當(dāng)當(dāng)前狀態(tài)下來(lái)個(gè)指定的事件,我才執(zhí)行它 
  75.         if (event == pActTable[i].event && CurState == pActTable[i].CurState) 
  76.         { 
  77.             flag = 1; 
  78.             eventActFun = pActTable[i].eventActFun; 
  79.             NextState = pActTable[i].NextState; 
  80.             break; 
  81.         } 
  82.     } 
  83.  
  84.  
  85.     if (flag) //如果滿足條件了 
  86.     { 
  87.         /*動(dòng)作執(zhí)行*/ 
  88.         if (eventActFun) 
  89.         { 
  90.             eventActFun(); 
  91.         } 
  92.  
  93.         //跳轉(zhuǎn)到下一個(gè)狀態(tài) 
  94.         fsmStateTransfer(pFsm, NextState); 
  95.     } 
  96.     else 
  97.     { 
  98.         printf("there is no match\n"); 
  99.     } 
  100.  
  101. int main() 
  102.     fsmType pType; 
  103.     fsmRegist(&pType,fTable); 
  104.     pType.curState = state_1; 
  105.     pType.size = sizeof(fTable)/sizeof(StateTable); 
  106.  
  107.  
  108.     printf("init state:%d\n\n",pType.curState); 
  109.  
  110.     fsmEventHandle(&pType,event_1); 
  111.     printf("state:%d\n\n",pType.curState); 
  112.  
  113.     fsmEventHandle(&pType,event_2); 
  114.     printf("state:%d\n\n",pType.curState); 
  115.  
  116.     fsmEventHandle(&pType,event_3); 
  117.     printf("state:%d\n\n",pType.curState); 
  118.  
  119.     fsmEventHandle(&pType,event_4); 
  120.     printf("state:%d\n\n",pType.curState); 
  121.  
  122.     fsmEventHandle(&pType,event_2); 
  123.     printf("state:%d\n\n",pType.curState); 
  124.  
  125.     return 0; 

編譯結(jié)果 

 

 

 

總結(jié)

使用函數(shù)指針實(shí)現(xiàn)的FSM的過(guò)程還是比較費(fèi)時(shí)費(fèi)力的,但是這一切相對(duì)一大堆的if/else、switch/case來(lái)說(shuō)都是值得的,當(dāng)你的程序規(guī)模變得越來(lái)越大的時(shí)候,基于這種表結(jié)構(gòu)的狀態(tài)機(jī),維護(hù)程序起來(lái)會(huì)清晰很多。 

責(zé)任編輯:龐桂玉 來(lái)源: C語(yǔ)言與C++編程
相關(guān)推薦

2021-12-28 08:24:18

函數(shù)指針有限狀態(tài)機(jī)編程

2024-10-10 17:46:06

2011-06-24 16:09:24

Qt 動(dòng)畫(huà) 狀態(tài)機(jī)

2023-03-06 07:35:30

狀態(tài)機(jī)工具訂單狀態(tài)

2025-10-29 07:38:45

2010-06-18 13:15:07

UML狀態(tài)機(jī)圖

2010-06-18 12:38:38

UML狀態(tài)機(jī)視圖

2021-07-08 09:15:20

單片機(jī)編程狀態(tài)機(jī)編程語(yǔ)言

2010-06-18 13:25:44

UML狀態(tài)機(jī)視圖

2013-09-03 09:57:43

JavaScript有限狀態(tài)機(jī)

2024-01-08 09:46:47

2011-06-29 18:36:59

Qt 動(dòng)畫(huà) 狀態(tài)機(jī)

2020-10-15 10:38:35

C語(yǔ)言狀態(tài)模型

2021-06-05 05:11:52

代碼狀態(tài)機(jī)邏輯

2010-07-08 13:03:31

UML狀態(tài)機(jī)圖

2020-03-27 10:50:29

DSL 狀態(tài)機(jī)工具

2010-07-12 15:00:56

UML狀態(tài)機(jī)視圖

2022-03-06 19:57:50

狀態(tài)機(jī)easyfsm項(xiàng)目

2021-08-19 09:00:00

微服務(wù)開(kāi)發(fā)架構(gòu)

2021-04-29 09:31:05

前端開(kāi)發(fā)技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)