matlab watershed函数简单实现_函数指针方法实现简单状态机(附代码)
之前写过一篇状态机的实用文章,很多朋友说有几个地方有点难度不易理解,今天给大家换种简单写法,使用函数指针的方法实现状态机。
状态机简介
有限状态机FSM是有限个状态及在这些状态之间的转移和动作等行为的数学模型,是一种逻辑单元内部的高效编程方法,可以根据不同状态或者消息类型进行相应的处理逻辑,使得程序逻辑清晰易懂。
函数指针实现FSM
使用函数指针实现FSM可以分为3个步骤
建立相应的状态表和动作查询表
根据状态表、事件、动作表定位相应的动作处理函数
执行完成后再进行状态的切换
代码实现步骤
- 定义状态数据的枚举类型
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 { //当且仅当当前状态下来个指定的事件,我才执行它 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
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 { //当且仅当当前状态下来个指定的事件,我才执行它 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;}
编译结果
总结
使用函数指针实现的FSM的过程还是比较费时费力的,但是这一切相对一大堆的if/else、switch/case
来说都是值得的,当你的程序规模变得越来越大的时候,基于这种表结构的状态机,维护程序起来会清晰很多。
matlab watershed函数简单实现_函数指针方法实现简单状态机(附代码)相关推荐
- c++ 取成员函数地址_c及c++指针及引用简单解释(自学学习心得)
从实参向形参传递参数时有两种方式可以使用: 1. 指针 使用指针传递时,如果目的是对实参的参数进行相关修改,则需要将实参变量的地址传递给形参,也就是说,形参需要定义为可以存放实参变量地址的变量,举个例 ...
- ostream作为函数返回值_函数的调用(一)
函数作为计算机代码的一种抽象方式,它的作用不言而喻! 原文链接 认识函数: 定义:函数是一段代码的表示,是一段具有特定功能的,可重用的语句组 函数是一种功能的抽象,一般函数表达特定功能 两个作用:降低 ...
- python-return_全局局部变量_函数名用法_函数嵌套
函数 1. return 返回值 作用: 自定义函数的返回值,return 可以把值返回到函数的调用处 return + 六大标准数据类型 , 还有类和对象,函数 如果不定义return ...
- python函数知识点总结_函数总结_python函数总结_高中函数知识点总结 - 云+社区 - 腾讯云...
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! postgresql窗口函数总结postgresql窗口函数总结 1窗口函数说明 ...
- 【C语言】函数的声明_函数定义_函数调用_函数递归 [函数的基本使用]
文章目录 前言 1.函数是什么? 2.C语言中函数的分类 2.1 库函数 2.2 自定义函数 3.函数的参数 3.1 实际参数(实参): 3.2 形式参数(形参): 4.函数的调用 4.1 传值调用 ...
- filter函数的用法_函数周期表丨筛选丨表丨CALCULATETABLE
CALCULATETABLE函数 CALCULATETABLE函数属于"筛选"类函数,隶属于"表函数". 某种意义上来说,CALCULATETABLE函数其实就 ...
- mysql函数输出参数_函数--返回值、参数和作用域
一.函数的返回值--return的作用 1.return将return后面的值作为函数的输出返回值,当函数被调用时,返回值可以被其他变量接收.使用. 而print只是打印在控制台,一个函数如果没有re ...
- gwo算法matlab源代码,智能优化算法应用:基于GWO优化BP神经网络 - 附代码
智能优化算法应用:基于GWO优化BP神经网络 - 附代码 智能优化算法应用:基于GWO优化BP神经网络 - 附代码 智能优化算法应用:基于GWO优化BP神经网络 文章目录智能优化算法应用:基于GWO优 ...
- 【Matlab 控制】仿真含时滞多智体一致性分析,附代码
Matlab 仿真含时滞多智体一致性分析,附代码 系统结构如下图所示: clear; clc; % 2014_多智能体网络的一致性问题研究_纪良浩 % 此为Paper中的示例代码 % 例2.1: A ...
最新文章
- Django modules模块
- 蓝桥杯-8-1因式分解(java)
- win10使用虚拟光驱安装vcenter6.7
- IOS15之JSON的解析字典转模型
- python创建虚拟环境时出现拒绝访问_无法创建虚拟环境
- php验证旧密码,PHP最佳实践之过滤、验证、转义和密码
- IDEA代码行宽设置
- 【转】处理wording的一些参考
- 解密Twitch:一家游戏直播网站缘何价值10亿刀?
- Sodinokibi勒索病毒利用Flash漏洞强势来袭
- 英特尔 超核芯显卡 620mac_十代i9+3080显卡,男孩们的攒机快乐,还得拿出来显摆显摆!...
- Python进阶读书笔记之(四) set集合
- 什么是现汇买入价、现钞买入价、卖…
- 回声状态网络(echo state network,ESN)概述
- C++中string类下的begin,end,rbegin,rend的用法
- 女程序员们的结婚要求
- 语中最美的十大经典爱情句子
- 点击修改按钮,将数据显示在弹层窗口中,利用ajax实现
- 计算机安全知识有哪些方面,计算机安全包括哪些方面
- Grail:Uber是如何管理大规模基础设施的
热门文章
- SAP Spartacus的登录验证机制 - user login Authentication
- 汪子熙微信公众号的写作计划
- SAP Spartacus服务器端渲染模式下的调试方法
- SAP CRM settype COMM_PROD_VAR
- setProperty will trigger ui re-render 南京同事提的问题
- SAP fiori backend determine cache setting
- when is this.oModel in sap-ui-core.js initialized for navigation working case
- Organization model change - product line item EC
- FioriLaunchpad.html的三个round-trip
- 用纯CSS实现3D立方体效果