状态机的基本实现手段是switch case语句,不过也可以用函数指针来实现。举例说明,这里有个switch case 实现的状态机。

switch case 实现的状态机

int count = 0;typedef enum {STATE1,STATE2,STATE3,
}state_t;state_t state = STATE1;void state_machine(void) {switch(state) {case STATE1:if(count > 3) { state = STATE2; }break;case STATE2:if(count > 10) { state = STATE3; }break;case STATE3:if(count > 100) { state = STATE1; }break;default:break;}
}int main(void) {for(;count < 200; count++) {state_machine();}return 0;
}

函数指针实现的状态机

int count = 0;typedef void (*state_t)(void);void STATE1(void);
void STATE2(void);
void STATE3(void);state_t state = STATE1;void STATE1(void) {if(count > 3) { state = STATE2; }
}void STATE2(void) {if(count > 10) { state = STATE3; }
}void STATE3(void) {if(count > 100) { state = STATE1; }
}int main(void) {for(;count < 200; count++) {state();}return 0;
}

改动内容包括:

  • 状态枚举的定义变更为状态处理函数指针的定义。
  • 每一个case语句分离成为状态处理函数。
  • 调用状态机的地方直接调用状态处理函数指针。

函数指针实现状态机的好处:

  • 进入状态处理的时间是固定的,无论有几个状态。使用switch case实现时,switch case默认情况下与 if else 语句生成的代码一致,要依次进行判断,进入后面状态处理的时间要比进入前面状态处理的时间要长。
  • 每个状态一个函数,函数的块头比较小,特别是状态处理的内容比较多的时候,分离成函数比较好阅读。

函数指针实现状态机的坏处:

  • 如果状态处理的内容很少,而状态很多,那么会分离成好多很小的函数。

更多内容

可以参考设计模式中的状态模式。

处理进入、退出状态

继续改造,加入处理事件的部分,这里仅给出进入、退出状态事件:

#include <stddef.h>int count;typedef enum {EV_DO,EV_ENTER,EV_EXIT,
}event_t;typedef void (*state_t)(event_t e);void trans(state_t next);
void STATE1(event_t e);
void STATE2(event_t e);
void STATE3(event_t e);state_t state = NULL;void STATE1(event_t e)
{switch(e) {case EV_DO:if(count > 3) { trans(STATE2); }break;case EV_ENTER:count = 0;break;default:break;}
}void STATE2(event_t e)
{switch(e) {case EV_DO:if(count > 10) { trans(STATE3);  }break;case EV_EXIT:count = 1;break;default:break;}
}void STATE3(event_t e)
{if(e == EV_DO) {if(count > 5) { trans(STATE1); }}
}void trans(state_t next)
{if(state) {state(EV_EXIT);}state = next;state(EV_ENTER);
}int main(void) {trans(STATE1);for(;count < 200; count++) {state(EV_DO);}return 0;
}

用函数指针来实现状态机相关推荐

  1. matlab watershed函数简单实现_函数指针方法实现简单状态机(附代码)

    之前写过一篇状态机的实用文章,很多朋友说有几个地方有点难度不易理解,今天给大家换种简单写法,使用函数指针的方法实现状态机. 状态机简介 有限状态机FSM是有限个状态及在这些状态之间的转移和动作等行为的 ...

  2. typedef函数指针_C语言函数指针之回调函数

    1 什么是回调函数? 首先什么是"回调"呢? 我的理解是:把一段可执行的代码像参数传递那样传给其他代码,而这段代码会在某个时刻被调用执行,这就叫做回调. 如果代码立即被执行就称为同 ...

  3. C语言——指针函数和函数指针(回调函数)

    前言:之前说了很多跟数组和指针相关的东西,这次从模块化编程降低耦合度的角度说下函数和指针的关系. 1. 指针函数   指针函数就是返回指针的函数.函数的返回类型有很多,void,int,char等都是 ...

  4. c/c++中的函数指针和指针函数

    定义 1.指针函数,本质是函数,返回值为指针,形如,int *pfun(int, int),由于"*"的优先级低于"()"的优先级,所以等同于int *(pfu ...

  5. 函数指针amp;绑定: boost::functoin/std::function/bind

    see link: https://isocpp.org/wiki/faq/pointers-to-members function vs template: http://stackoverflow ...

  6. 0709 C语言常见误区----------函数指针问题

    1.函数指针的定义 对于函数 void test(int a, int b){ // } 其函数指针类型是void (* ) (int , int), 注意这里第一个括号不能少, 定义一个函数指针,v ...

  7. java跨函数跳转_C语言中将绝对地址转换为函数指针以及跳转到内存指定位置处执行的技巧...

    1.方法一 要对绝对地址0x100000赋值,我们可以用 (unsigned int  * ) 0x100000 = 1234; 那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做? ...

  8. 函数指针(就做个笔记)

    1,函数的地址 #include <stdio.h> int main(){int i=0;printf("main=%p\n",main);printf(" ...

  9. 函数指针--Nginx和Redis中两种回调函数写法

    1.Nginx和Redis中两种回调函数写法 #include <stdio.h>//仿Nginx风格 //结构外声明函数指针类型 typedef void (*ngx_connectio ...

最新文章

  1. seaborn使用violinplot函数可视化小提琴图、并在violinplot函数中设置inner参数来添加数据点显示数据的稠密程度
  2. python列表知识点_Python列表知识点
  3. 超详综述 | 基于深度学习的命名实体识别
  4. java监听某端口和ip_Java 通过Socket监听指定服务器(IP)的指定端口,及向指定服务器的指定端口发送信息...
  5. Boost:cpu时间的实例
  6. ubuntu 设置大小写切换隐藏_VirtualBox中ubuntu的LAMP项目(温度采集)
  7. Jmeter之Bean shell使用(四)——跨线程组之间的全局参数传递
  8. Javascript 对象一(对象详解)
  9. java 随机化快速排序,JS实现随机化快速排序的实例代码
  10. commands moudle on python will replace with subprocess on py3.0
  11. 真深复制python_Python深复制浅复制or深拷贝浅拷贝
  12. Flutter进阶第6篇: 获取设备信息 以及 使用高德Api获取地理位置
  13. 关于cmwap和cmnet之间的区别
  14. 中国象棋马走日 — 递归
  15. Agile PLM 表结构说明
  16. android限制app运行时间限制,android app 限制app使用时间
  17. Word目录排版,页码格式转换
  18. mt4交易软件云服务器_MT4交易软件的使用教程及快捷键
  19. Win10 下Go语言和Goland的下载和环境配置
  20. Learned Motion Matching-动作生成算法

热门文章

  1. Carbide LED进行闪烁的设置
  2. 期货自动化反向算法数据统计
  3. chrome浏览器扩展安装
  4. SwiftUI 2.0 课程笔记 Chapter 8
  5. tslint.json
  6. 数据库内存emoji图标
  7. S3C2440 流水灯 (TQ2440)
  8. 钉钉「中国酷公司」发布会图文全纪录(首发)
  9. 实时监控网络流量,精准辨别网络性能瓶颈
  10. 基于 ZEGO SDK 实现 iOS 一对一音视频聊天应用