本篇内容主要讲解“函数指针方法怎么实现简单状态机”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“函数指针方法怎么实现简单状态机”吧!
状态机简介
有限状态机FSM是有限个状态及在这些状态之间的转移和动作等行为的数学模型,是一种逻辑单元内部的高效编程方法,可以根据不同状态或者消息类型进行相应的处理逻辑,使得程序逻辑清晰易懂。
函数指针实现FSM
使用函数指针实现FSM可以分为3个步骤
鸿蒙官方战略合作共建——HarmonyOS技术社区
建立相应的状态表和动作查询表
根据状态表、事件、动作表定位相应的动作处理函数
执行完成后再进行状态的切换
代码实现步骤
1.定义状态数据的枚举类型
typedef enum { state_1=1, state_2, state_3, state_4 }State;
2.定义事件的枚举类型
typedef enum{ event_1=1, event_2, event_3, event_4, event_5 }EventID;
3.定义状态表的数据类型
typedef struct { int event; //事件 int CurState; //当前状态 void (*eventActFun)(); //函数指针 int NextState; //下一个状态 }StateTable;
4.定义处理函数及建立状态表
void f121() { printf("this is f121\n"); } void f221() { printf("this is f221\n"); } void f321() { printf("this is f321\n"); } void f122() { printf("this is f122\n"); } StateTable fTable[] = { //{到来的事件,当前的状态,将要要执行的函数,下一个状态} { event_1, state_1, f121, event_2 }, { event_2, state_2, f221, event_3 }, { event_3, state_3, f321, event_4 }, { event_4, state_4, f122, event_1 }, //add your code here };
5.状态机类型,及状态机接口函数
/*状态机类型*/ typedef struct { int curState;//当前状态 StateTable * stateTable;//状态表 int size;//表的项数 }fsmType; /*状态机注册,给它一个状态表*/ void fsmRegist(fsmType* pFsm, StateTable* pTable) { pFsm->stateTable = pTable; } /*状态迁移*/ void fsmStateTransfer(fsmType* pFsm, int state) { pFsm->curState = state; } /*事件处理*/ void fsmEventHandle(fsmType* pFsm, int event) { StateTable* pActTable = pFsm->stateTable; void (*eventActFun)() = NULL; //函数指针初始化为空 int NextState; int CurState = pFsm->curState; int maxNum = pFsm->size; int flag = 0; //标识是否满足条件 /*获取当前动作函数*/ for (int i = 0; i<maxNum; i++) { //当且仅当当前状态下来个指定的事件,我才执行它 if (event == pActTable[i].event && CurState == pActTable[i].CurState) { flag = 1; eventActFun = pActTable[i].eventActFun; NextState = pActTable[i].NextState; break; } } if (flag) //如果满足条件了 { /*动作执行*/ if (eventActFun) { eventActFun(); } //跳转到下一个状态 fsmStateTransfer(pFsm, NextState); } else { printf("there is no match\n"); } }
附代码
代码直接复制过去就行啦,本想打包的,太麻烦了。
测试程序
//编译器:http://www.dooccn.com/cpp/ //来源:技术让梦想更伟大 //作者:李肖遥 #include <stdio.h> typedef enum { state_1=1, state_2, state_3, state_4 }State; typedef enum{ event_1=1, event_2, event_3, event_4, event_5 }EventID; typedef struct { int event; //事件 int CurState; //当前状态 void (*eventActFun)(); //函数指针 int NextState; //下一个状态 }StateTable; void f121() { printf("this is f121\n"); } void f221() { printf("this is f221\n"); } void f321() { printf("this is f321\n"); } void f122() { printf("this is f122\n"); } StateTable fTable[] = { //{到来的事件,当前的状态,将要要执行的函数,下一个状态} { event_1, state_1, f121, event_2 }, { event_2, state_2, f221, event_3 }, { event_3, state_3, f321, event_4 }, { event_4, state_4, f122, event_1 }, //add your code here }; /*状态机类型*/ typedef struct { int curState;//当前状态 StateTable * stateTable;//状态表 int size;//表的项数 }fsmType; /*状态机注册,给它一个状态表*/ void fsmRegist(fsmType* pFsm, StateTable* pTable) { pFsm->stateTable = pTable; } /*状态迁移*/ void fsmStateTransfer(fsmType* pFsm, int state) { pFsm->curState = state; } /*事件处理*/ void fsmEventHandle(fsmType* pFsm, int event) { StateTable* pActTable = pFsm->stateTable; void (*eventActFun)() = NULL; //函数指针初始化为空 int NextState; int CurState = pFsm->curState; int maxNum = pFsm->size; int flag = 0; //标识是否满足条件 /*获取当前动作函数*/ for (int i = 0; i<maxNum; i++) { //当且仅当当前状态下来个指定的事件,我才执行它 if (event == pActTable[i].event && CurState == pActTable[i].CurState) { flag = 1; eventActFun = pActTable[i].eventActFun; NextState = pActTable[i].NextState; break; } } if (flag) //如果满足条件了 { /*动作执行*/ if (eventActFun) { eventActFun(); } //跳转到下一个状态 fsmStateTransfer(pFsm, NextState); } else { printf("there is no match\n"); } } int main() { fsmType pType; fsmRegist(&pType,fTable); pType.curState = state_1; pType.size = sizeof(fTable)/sizeof(StateTable); printf("init state:%d\n\n",pType.curState); fsmEventHandle(&pType,event_1); printf("state:%d\n\n",pType.curState); fsmEventHandle(&pType,event_2); printf("state:%d\n\n",pType.curState); fsmEventHandle(&pType,event_3); printf("state:%d\n\n",pType.curState); fsmEventHandle(&pType,event_4); printf("state:%d\n\n",pType.curState); fsmEventHandle(&pType,event_2); printf("state:%d\n\n",pType.curState); return 0; }
编译结果
到此,相信大家对“函数指针方法怎么实现简单状态机”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。