当前位置: 首页 > 科技观察

函数指针方法实现简单状态机(附代码)

时间:2023-03-19 12:44:51 科技观察

之前写过一篇状态机实战文章。很多朋友说有几个地方有点难懂。今天给大家简单的写法,用函数指针的方式实现一个状态机。状态机介绍有限状态机FSM是有限数量的状态和这些状态之间的转换和动作等行为的数学模型。它是一种逻辑单元内部的高效编程方法,可以根据不同的状态或消息类型执行相应的处理逻辑,使程序逻辑清晰易懂。用函数指针实现FSM使用函数指针实现FSM可以分为3个步骤。建立相应的状态表和动作查询表。根据状态表、事件、动作表定位到对应的动作。处理函数执行完毕后,实现状态切换代码。Step1.定义状态数据的枚举类型typedefenum{state_1=1,state_2,state_3,state_4}State;2、定义事件的枚举类型typedefenum{event_1=1,event_2,event_3,event_4,event_5}EventID;3.定义状态表数据类型typedefstruct{inevent;//事件intCurState;//当前状态void(*eventActFun)();//函数指针intNextState;//下一个状态}StateTable;4、定义处理函数,建立状态表);}voidf122(){printf("thisisf122\n"");}StateTablefTable[]={//{即将发生的事件,当前状态,要执行的函数,下一个状态}{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},//addyourcodehere};5.状态机类型,以及状态机接口函数/*statemachinetype*/typedefstruct{intcurState;//当前状态StateTable*stateTable;//状态表intsize;//表项数}fsmType;/*状态机注册,给它一张状态表*/voidfsmRegist(fsmType*pFsm,StateTable*pTable){pFsm->stateTable=pTable;}/*状态转换*/voidfsmStateTransfer(fsmType*pFsm,intstate){pFsm->curState=state;}/*事件处理*/voidfsmEventHandle(fsmType*pFsm,inevent){StateTable*pActTable=pFsm->stateTable;void(*eventActFun)()=NULL;//函数指针初始化为空intNextState;intCurState=pFsm->curState;intmaxNum=pFsm->size;intflag=0;//判断是否满足条件/*获取当前动作函数*/for(inti=0;itypedefenum{state_1=1,state_2,state_3,state_4}State;typedefenum{event_1=1,event_2,event_3,event_4,event_5}EventID;typedefstruct{inevent;//事件intCurState;//当前状态void(*eventActFun)();//函数指针intNextState;//下一个状态}StateTable;voidf121(){printf("thisisf121\n");}voidf221(){printf("thisisf221\n");}voidf321(){printf("thisisf321\n");}voidf122(){printf("thisisf122\n");}StateTablefTable[]={//{即将发生的事件,当前状态,要执行的函数,下一个状态}{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},//addyourcodehere};/*状态机类型*/typedefstruct{intcurState;//当前状态StateTable*stateTable;//状态表intsize;//表项数}fsmType;/*状态机注册,给它一张状态表*/voidfsmRegist(fsmType*pFsm,StateTable*pTable){pFsm->stateTable=pTable;}/*状态迁移*/voidfsmStateTransfer(fsmType*pFsm,intstate){pFsm->curState=state;}/*事件处理*/voidfsmEventHandle(fsmType*pFsm,inevent){StateTable*pActTable=pFsm->stateTable;void(*eventActFun)()=NULL;//函数指针初始化为空intNextState;intCurState=pFsm->curState;intmaxNum=pFsm->size;intflag=0;//判断是否满足条件/*获取当前动作函数*/for(inti=0;i