函数指针方法怎么实现简单状态机

发布时间:2021-10-23 11:04:04 作者:iii
来源:亿速云 阅读:149

本篇内容主要讲解“函数指针方法怎么实现简单状态机”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“函数指针方法怎么实现简单状态机”吧!

状态机简介

有限状态机FSM是有限个状态及在这些状态之间的转移和动作等行为的数学模型,是一种逻辑单元内部的高效编程方法,可以根据不同状态或者消息类型进行相应的处理逻辑,使得程序逻辑清晰易懂。

函数指针实现FSM

使用函数指针实现FSM可以分为3个步骤

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 建立相应的状态表和动作查询表

  3. 根据状态表、事件、动作表定位相应的动作处理函数

  4. 执行完成后再进行状态的切换

代码实现步骤

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; }

编译结果

函数指针方法怎么实现简单状态机

到此,相信大家对“函数指针方法怎么实现简单状态机”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. TCP/IP状态机
  2. java函数指针使用方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c语言

上一篇:在Windows 10中如何使用Diskpart命令管理磁盘

下一篇:怎么在Fedora中添加第三方存储库以访问大量附加软件

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》