博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C/C++用状态转移表联合函数指针数组实现状态机FSM
阅读量:4977 次
发布时间:2019-06-12

本文共 2728 字,大约阅读时间需要 9 分钟。

状态机在project中使用很的频繁,有例如以下常见的三种实现方法:

1. switch-case 实现。适合简单的状态机。
2. 二维状态表state-event实现。逻辑清晰。可是矩阵通常比較稀疏,并且维护麻烦。
3. 用状态转移表stateTransfer Table实现,数组大小等于状体转移边个数,易扩展;
以下用一个样例来进行具体说明,描写叙述的例如以下场景:

描写叙述对象:门

状态:开着、关着、锁着 (这里的关着指关了但未锁的状态)
事件:开门、关门、上锁、解锁

代码实现用枚举来定义状态和事件,操作数据节点转移到目的状态用函数实现。枚举本身默认是从0開始的int类型,利用这个特点将状态转移函数放到函数指针数组中与状态相应起来。方便操作。

核心数据结构例如以下:

状态:枚举类型

事件:枚举类型
状态转移结构体:{当前状态、事件、下个状态},定义一个全局数组来使用
状态变更函数:到下个状态(放到数组中与状态枚举相应起来)

此种实现方法easy扩展,添加状态和事件都比較easy。

假设存在一个状态通过相应事件能够转移到多个状态的情形,则能够扩展状态转移函数。或者在状态转移结构中添加一个推断函数字段。

代码实现例如以下:

#include 
using namespace std;typedef enum{ OPENED, CLOSED, LOCKED,} State;typedef enum{ OPEN, CLOSE, LOCK, UNLOCK} Event;typedef struct{ State currentState; Event event; State NextState;} StateTransfer;typedef struct{ State state; int transferTimes;}Door;StateTransfer g_stateTransferTable[]{ {OPENED, CLOSE, CLOSED}, {CLOSED, OPEN, OPENED}, {CLOSED, LOCK, LOCKED}, {LOCKED, UNLOCK, CLOSED},};void toOpen(Door& door);void toClose(Door& door);void toLock(Door& door);typedef void (*pfToState)(Door& door);pfToState g_pFun[] = {toOpen, toClose, toLock}; //状态枚举值相应下标void toOpen(Door& door){ door.state = OPENED; cout << "open the door!\n";}void toClose(Door& door){ door.state = CLOSED; cout << "close the door!\n";}void toLock(Door& door){ door.state = LOCKED; cout << "lock the door!\n";}void transfer(Door& door,const Event event){ for (int i = 0; i < sizeof(g_stateTransferTable)/sizeof(StateTransfer); ++i) { if(door.state == g_stateTransferTable[i].currentState && event == g_stateTransferTable[i].event){ g_pFun[g_stateTransferTable[i].NextState](door); door.transferTimes++; cout << "transfer ok!\n"; return; } } cout << "This event cannot transfer current state!!\n"; return;}void printDoor(const Door& door){ string stateNote[] = {
"opened","closed","locked"}; // 下标正好相应状态枚举值 cout << "the door's state is: " << stateNote[door.state] << endl; cout << "the door transfer times is: " << door.transferTimes << endl;}int main(){ Door door = {CLOSED, 0}; printDoor(door); transfer(door, OPEN); printDoor(door); transfer(door, LOCK); printDoor(door); transfer(door, CLOSE); printDoor(door); return 0;}

执行结果例如以下:

the door’s state is: closed

the door transfer times is: 0
open the door!
transfer ok!
the door’s state is: opened
the door transfer times is: 1
This event cannot transfer current state!!
the door’s state is: opened
the door transfer times is: 1
close the door!
transfer ok!
the door’s state is: closed
the door transfer times is: 2

转载于:https://www.cnblogs.com/lxjshuju/p/7162232.html

你可能感兴趣的文章
Where does Visual Studio look for C++ Header files?
查看>>
Java打包可执行jar包 包含外部文件
查看>>
Windows Phone开发(37):动画之ColorAnimation
查看>>
js中escape,encodeURI,encodeURIComponent 区别(转)
查看>>
sass学习笔记-安装
查看>>
Flask (二) cookie 与 session 模型
查看>>
修改添加网址的教程文件名
查看>>
[BZOJ 1017][JSOI2008]魔兽地图DotR(树形Dp)
查看>>
裁剪图片
查看>>
数据结构实习 problem L 由二叉树的中序层序重建二叉树
查看>>
VS中展开和折叠代码
查看>>
如何确定VS编译器版本
查看>>
设置PL/SQL 快捷键
查看>>
个人阅读作业7
查看>>
转载:深入浅出Zookeeper
查看>>
GMA Round 1 新程序
查看>>
node anyproxy ssi简易支持
查看>>
编译预处理指令:文件包含指令、宏定义指令、条件编译指令
查看>>
PHP函数 ------ ctype_alnum
查看>>
网站安全
查看>>