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

《编程之美》函数指针的方法实现一个简单的状态机(附代码)

时间:2023-03-14 13:04:18 科技观察

之前写过一篇关于状态机的实战文章。很多朋友说有几个地方有点难懂。今天给大家介绍一种简单的写法。使用函数指针的方法实现状态机。状态机介绍有限状态机FSM是有限数量的状态和这些状态之间的转换和动作等行为的数学模型。它是一种逻辑单元内部的高效编程方法,可以根据不同的状态或消息类型执行相应的处理逻辑,使程序逻辑清晰易懂。用函数指针实现FSM使用函数指针实现FSM可以分为3个步骤。建立相应的状态表和动作查询表。根据状态表、事件、动作表定位相应的动作处理函数。状态数据类型的枚举类型defenum{state_1=1,state_2,state_3,state_4}State;定义事件的枚举类型typedefenum{event_1=1,event_2,event_3,event_4,event_5}EventID;定义状态表的数据类型typedefstruct{intent;//事件intCurState;//当前状态void(*eventActFun)();//函数指针intNextState;//下一个状态}StateTable;定义处理函数并建立状态表(){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->大小;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