C函数指针状态机实现
C函数指针状态机实现
有限状态机(finite state machine)简称FSM,表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用。FSM是一种逻辑单元内部的一种高效编程方法,在服务器编程中,服务器可以根据不同状态或者消息类型进行相应的处理逻辑,使得程序逻辑清晰易懂。
#include <stdio.h> //函数指针实现FSM enum year_state { SPRING = , SUMMER, AUTUMN, WINTER }; enum year_event { EVENT1 = , EVENT2, EVENT3, EVENT4 }; typedef struct FsmTable_s { int event; // 事件 int CurState; // 当前状态 void (*eventActFun)(); //函数指针 int nextState; // 下一个状态 } FsmTable_t; void spring_thing() { printf("this is spring\n"); } void summer_thing() { printf("this is summer\n"); } void autumn_thing() { printf("this is autumn\n"); } void winter_thing() { printf("this is winter\n"); } FsmTable_t year_table[] = { //{到来的事件,当前的状态,将要要执行的函数,下一个状态} { EVENT1, SPRING, summer_thing, SUMMER }, { EVENT2, SUMMER, autumn_thing, AUTUMN }, { EVENT3, AUTUMN, winter_thing, WINTER }, { EVENT4, WINTER, spring_thing, SPRING }, //add your codes here }; typedef struct FSM_s { int curState;//当前状态 FsmTable_t * pFsmTable;//状态表 int size;//表的项数 } FSM_t; /*状态机注册,给它一个状态表*/ void FSM_Regist(FSM_t *pFSM, FsmTable_t *pFsmTable) { pFSM->pFsmTable = pFsmTable; } /*状态迁移*/ void FSM_StateTransfer(FSM_t* pFsm, int state) { pFsm->curState = state; } /*事件处理*/ void FSM_EventHandle(FSM_t* pFsm, int event) { FsmTable_t* pActTable = pFsm->pFsmTable; void (*eventActFun)() = NULL; //函数指针初始化为空 int NextState; int CurState = pFsm->curState; int g_max_num = pFsm->size; ; //标识是否满足条件 int i; ; i < g_max_num; i++) { if (event == pActTable[i].event && CurState == pActTable[i].CurState) { flag = ; eventActFun = pActTable[i].eventActFun; NextState = pActTable[i].nextState; break; } } if (flag) { if (eventActFun) { eventActFun(); } FSM_StateTransfer(pFsm, NextState); } else { printf("There is no match\n"); } } int main() { FSM_t year_fsm; FSM_Regist(&year_fsm, year_table); year_fsm.curState = SPRING; year_fsm.size = sizeof(year_table)/sizeof(FsmTable_t); printf("\n-------1--init spring------\n"); printf("state:%d\n",year_fsm.curState); printf("\n-------2--spring->summer------\n"); FSM_EventHandle(&year_fsm,EVENT1); printf("state:%d\n",year_fsm.curState); printf("\n-------3--summer->autumn------\n"); FSM_EventHandle(&year_fsm,EVENT2); printf("state:%d\n",year_fsm.curState); printf("\n-------4--autumn->winter------\n"); FSM_EventHandle(&year_fsm,EVENT3); printf("state:%d\n",year_fsm.curState); printf("\n-------5--winter->spring------\n"); FSM_EventHandle(&year_fsm,EVENT4); printf("state:%d\n",year_fsm.curState); printf("\n-------6--receive EVENT2 not EVENT1------\n"); FSM_EventHandle(&year_fsm,EVENT2); printf("state:%d\n",year_fsm.curState); }
C函数指针状态机实现的更多相关文章
- C/C++用状态转移表联合函数指针数组实现状态机FSM
状态机在project中使用很的频繁,有例如以下常见的三种实现方法: 1. switch-case 实现.适合简单的状态机. 2. 二维状态表state-event实现.逻辑清晰.可是矩阵通常比較稀疏 ...
- C++虚函数和函数指针一起使用
C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...
- 为什么 C++ 中成员函数指针是 16 字节?
当我们讨论指针时,通常假设它是一种可以用 void * 指针来表示的东西,在 x86_64 平台下是 8 个字节大小.例如,下面是来自 维基百科中关于 x86_64 的文章 的摘录: Pushes a ...
- C++函数指针总结
学习c++的过程中,指针是难点,熟悉了指针之后,还有一个让人很蛋疼的难点,那就是函数指针了.本博文详细介绍一下常见的各种坑爹的函数指针. 至于指针的详细学习,推荐这篇博文C++指针详解 与数据一样,函 ...
- C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用
类型 普通指针 指针数组(非指针类型) 数组指针 结构体指针 函数指针 二重指针 定义方式 int *p; int *p[5]; int (*p)[5]; int a[3][5]; struct{.. ...
- 结构体内嵌函数指针实现C语言面向对象
结构体内嵌函数指针 #include<stdio.h> void say(int age) { printf("我%d岁了\n",age); } struct stud ...
- 用typedef定义函数指针的问题
在学习windows API的时候,遇到下面这段代码 以前见过的typedef的用法都是给一个数据类型取一个别名 typedef oldTypeName newTypeName 这种给数据类型 ...
- 你必须知道的指针基础-7.void指针与函数指针
一.不能动的“地址”—void指针 1.1 void指针初探 void *表示一个“不知道类型”的指针,也就不知道从这个指针地址开始多少字节为一个数据.和用int表示指针异曲同工,只是更明确是“指针” ...
- objective-c中的@selector()和 c /c++的函数指针
先看tomcat里用到的代码: //然后开始动画 //把图片放到animationImages,接受数组参数 self.tom.animationImages = arrayImage; //设置时间 ...
随机推荐
- Unity3D热更新之LuaFramework篇[07]--怎么让unity对象绑定Lua脚本
前言 在上一篇文章 Unity3D热更新之LuaFramework篇[06]--Lua中是怎么实现脚本生命周期的 中,我分析了由LuaBehaviour来实现lua脚本生命周期的方法. 但在实际使用中 ...
- Go语言圣经习题练习_1.5. 获取URL
练习 1.7: 函数调用io.Copy(dst, src)会从src中读取内容,并将读到的结果写入到dst中,使用这个函数替代掉例子中的ioutil.ReadAll来拷贝响应结构体到os.Stdout ...
- 使用GDAL实现DEM的地貌晕渲图(三)
目录 1. 原理 1) ArcMap生成彩色晕渲图 2) 彩色色带赋值 3) 颜色叠加 2. 实现 3. 结语 4. 参考 1. 原理 之前在<使用GDAL实现DEM的地貌晕渲图(一)>和 ...
- ES 22 - Elasticsearch中如何进行日期(数值)范围查询
目录 1 范围查询的符号 2 数值范围查询 3 时间范围查询 3.1 简单查询示例 3.2 关于时间的数学表达式(date-math) 3.3 关于时间的四舍五入 4 日期格式化范围查询(format ...
- NDK jni mk文件 so文件 巴啦啦 初体验
概念JNI(Java Native Interface,Java本地接口),实现了Java和其他语言的交互(主要是C/C++),如:Java程序通过JNI调用C/C++编写的在Windows上运行的D ...
- js常用事件列表
onmousedown.onmouseup 以及 onclick 事件 onmousedown, onmouseup 以及 onclick 构成了鼠标点击事件的所有部分.首先当点击鼠标按钮时,会触发 ...
- .net core 基于 IHostedService 实现定时任务
.net core 基于 IHostedService 实现定时任务 Intro 从 .net core 2.0 开始,开始引入 IHostedService,可以通过 IHostedService ...
- 插入Oracle数据库后返回当前主键id
最近做一个spring版本3.0.4的老项目功能,应用场景要用到插入oracle表后返回主键ID拿来和其他表关联. 用oralce的可以一直用这种处理方式,高兼容低,搜索网上的资料都不能和这个Spri ...
- Placement_pools on Rados-GW
The purpose of this test is to map a RadosGw Bucket to a specific Ceph pool. For exemple, if using a ...
- UR机器人的位姿
一.Ur 移动命令 UR机器人移动,一共有三种移动指令,movej,movel,movep,分别是关节运动,线性运动,圆周运动. movej:6个关节的弧度 movel/movep:分别是x,y,z, ...