当前位置: 首页 > news >正文

状态机的实现方法--C语言版本

状态机(State Machine)用于表示有限个状态以及在这些状态之间的转移和动作。在计算机科学中,状态机常用于建模程序的行为,尤其是那些需要根据输入或事件改变行为的系统。

状态机的实现方式有多种,常见的有:

  1. 使用switch-case语句

  2. 使用状态表(State Table)

  3. 使用函数指针(State Function Pointer)

1. 使用switch-case语句

这种方式是最直接的状态机实现方法。通过一个循环和switch语句,根据当前状态和输入事件执行相应的操作,并转换状态。

示例:一个简单的状态机,有两个状态:STATE_A和STATE_B,两个事件:EVENT_1和EVENT_2。

状态转移规则:

  1. 在STATE_A下,遇到EVENT_1则执行动作A1并转移到STATE_B;遇到EVENT_2则执行动作A2并保持在STATE_A。

  2. 在STATE_B下,遇到EVENT_1则执行动作B1并保持在STATE_B;遇到EVENT_2则执行动作B2并转移到STATE_A

#include <stdio.h>// 定义状态和事件
typedef enum {STATE_A,STATE_B
} State;typedef enum {EVENT_1,EVENT_2
} Event;// 状态机函数
void state_machine(Event event) {static State current_state = STATE_A;switch (current_state) {case STATE_A:switch (event) {case EVENT_1:printf("在STATE_A处理EVENT_1,执行动作A1,转移到STATE_B\n");current_state = STATE_B;break;case EVENT_2:printf("在STATE_A处理EVENT_2,执行动作A2,保持在STATE_A\n");break;}break;case STATE_B:switch (event) {case EVENT_1:printf("在STATE_B处理EVENT_1,执行动作B1,保持在STATE_B\n");break;case EVENT_2:printf("在STATE_B处理EVENT_2,执行动作B2,转移到STATE_A\n");current_state = STATE_A;break;}break;}
}int main() {// 模拟事件序列state_machine(EVENT_1);state_machine(EVENT_2);state_machine(EVENT_1);state_machine(EVENT_1);return 0;
}

2. 使用状态表(State Table)

状态表是一个二维数组,其中行表示当前状态,列表示事件,每个单元格包含下一个状态和要执行的动作。这种方式适用于状态和事件较多的情况,可以清晰地表示状态转移。

示例:同样实现上面的状态机。

#include <stdio.h>// 定义状态和事件
typedef enum {STATE_A,STATE_B,STATE_COUNT
} State;typedef enum {EVENT_1,EVENT_2,EVENT_COUNT
} Event;// 定义动作函数指针
typedef void (*Action)(void);// 动作函数
void action_A1() { printf("执行动作A1\n"); }
void action_A2() { printf("执行动作A2\n"); }
void action_B1() { printf("执行动作B1\n"); }
void action_B2() { printf("执行动作B2\n"); }// 状态表项,包含下一个状态和要执行的动作
typedef struct {State next_state;Action action;
} Transition;// 状态表
Transition state_table[STATE_COUNT][EVENT_COUNT] = {[STATE_A] = {[EVENT_1] = {STATE_B, action_A1},[EVENT_2] = {STATE_A, action_A2}},[STATE_B] = {[EVENT_1] = {STATE_B, action_B1},[EVENT_2] = {STATE_A, action_B2}}
};// 状态机函数
void state_machine(Event event) {static State current_state = STATE_A;Transition transition = state_table[current_state][event];transition.action();current_state = transition.next_state;
}int main() {state_machine(EVENT_1);state_machine(EVENT_2);state_machine(EVENT_1);state_machine(EVENT_1);return 0;
}

3. 使用函数指针(State Function Pointer)

这种方式将每个状态实现为一个函数,函数内部根据事件决定下一个状态和要执行的动作。状态机维护一个当前状态的函数指针,当事件发生时,调用当前状态对应的函数。

示例:同样实现上面的状态机

#include <stdio.h>// 定义状态和事件
typedef enum {EVENT_1,EVENT_2
} Event;// 前向声明状态函数
typedef void (*StateFunction)(Event);// 状态函数声明
void state_a(Event event);
void state_b(Event event);// 全局状态变量,保存当前状态的函数指针
StateFunction current_state = state_a;// 状态A的处理函数
void state_a(Event event) {switch (event) {case EVENT_1:printf("在STATE_A处理EVENT_1,执行动作A1,转移到STATE_B\n");current_state = state_b;break;case EVENT_2:printf("在STATE_A处理EVENT_2,执行动作A2,保持在STATE_A\n");break;}
}// 状态B的处理函数
void state_b(Event event) {switch (event) {case EVENT_1:printf("在STATE_B处理EVENT_1,执行动作B1,保持在STATE_B\n");break;case EVENT_2:printf("在STATE_B处理EVENT_2,执行动作B2,转移到STATE_A\n");current_state = state_a;break;}
}// 状态机函数
void state_machine(Event event) {current_state(event);
}int main() {state_machine(EVENT_1);state_machine(EVENT_2);state_machine(EVENT_1);state_machine(EVENT_1);return 0;
}

4. 面向对象方式(使用结构体)

#include <stdio.h>
#include <stdlib.h>// 定义状态和事件
typedef enum {STATE_OFF,STATE_ON,STATE_SLEEP
} State;typedef enum {EVENT_POWER_ON,EVENT_POWER_OFF,EVENT_SLEEP,EVENT_WAKE_UP
} Event;// 状态机结构体
typedef struct {State current_state;void (*on_enter)(void);void (*on_exit)(void);
} StateMachine;// 状态进入和退出函数
void enter_off(void) { printf("进入关闭状态\n"); }
void exit_off(void) { printf("退出关闭状态\n"); }void enter_on(void) { printf("进入开启状态\n"); }
void exit_on(void) { printf("退出开启状态\n"); }void enter_sleep(void) { printf("进入睡眠状态\n"); }
void exit_sleep(void) { printf("退出睡眠状态\n"); }// 状态转移表
typedef struct {State current;Event event;State next;
} Transition;Transition transitions[] = {{STATE_OFF,   EVENT_POWER_ON,  STATE_ON},{STATE_ON,    EVENT_POWER_OFF, STATE_OFF},{STATE_ON,    EVENT_SLEEP,     STATE_SLEEP},{STATE_SLEEP, EVENT_WAKE_UP,   STATE_ON},{STATE_SLEEP, EVENT_POWER_OFF, STATE_OFF}
};#define TRANSITION_COUNT (sizeof(transitions) / sizeof(transitions[0]))// 状态机处理函数
void handle_event(StateMachine *sm, Event event) {for (int i = 0; i < TRANSITION_COUNT; i++) {if (transitions[i].current == sm->current_state && transitions[i].event == event) {// 执行退出当前状态if (sm->on_exit) sm->on_exit();// 更新状态sm->current_state = transitions[i].next;// 执行进入新状态if (sm->on_enter) sm->on_enter();return;}}printf("无效的状态转移: 状态=%d, 事件=%d\n", sm->current_state, event);
}int main() {StateMachine sm = {.current_state = STATE_OFF,.on_enter = enter_off,.on_exit = NULL};handle_event(&sm, EVENT_POWER_ON);handle_event(&sm, EVENT_SLEEP);handle_event(&sm, EVENT_WAKE_UP);handle_event(&sm, EVENT_POWER_OFF);return 0;
}

总结

实现方式优点缺点适用场景
嵌套switch简单直观,易于理解状态多时代码冗长,维护困难简单状态机
状态表结构清晰,易于扩展需要额外的表结构,稍复杂复杂状态机
函数指针灵活,状态逻辑封装好状态间耦合可能较高中等复杂度
面向对象结构清晰,易于维护C语言实现稍繁琐复杂系统

选择哪种方式取决于状态机的复杂度、可维护性需求和性能要求。对于简单状态机,嵌套switch足够;对于复杂系统,推荐使用状态表或面向对象方式。

http://www.dtcms.com/a/598944.html

相关文章:

  • 网站做app开发有梦商城公司网站
  • 网站开发系统毕业综合实践报告电子版个人简历模板
  • 线代强化NO5|矩阵的运算法则|分块矩阵|逆矩阵|伴随矩阵|初等矩阵
  • 最新域名网站查询网站背景大小
  • 服装网站建设发展状况wordpress数据库访问慢
  • 大同市住房城乡建设网站扬州网站建设 天维
  • nat123做网站 查封编写网站的软件
  • 天津房地产网站建设福建联美建设集团有限公司网站
  • 简述网站建设有哪些步骤有什么网站可以做推广
  • C语言进阶:位操作
  • 建站网站苏州wordpress架设系统
  • wordpress短代码返回html石家庄网站seo优化
  • python合适做网站吗网站建设与维护面试
  • 什么是Hinge损失函数
  • 网站设计的趋势百度双站和响应式网站的区别
  • usrsctp之cookie
  • CC防护:抵御应用层攻击的精确防线
  • 如何自己制作链接内容泰安网站建设优化
  • 芜湖哪里做网站亚马逊雨林的资料
  • Manus高精度动捕数据手套,Metagloves Pro对比Quantum Metagloves:谁是你的灵巧手研发最佳选择?
  • 佛山网站建设3lue3lue修改图片网站
  • 【开题答辩实录分享】以《中医古籍管理系统》为例进行答辩实录分享
  • 做网站时如何给文字做超链接网络服务提供者知道网络用户利用其网络服务
  • [Windows] 火绒弹窗拦截6.0.8.0、5.0.78.2-2025.11.05.1绿色独立版
  • 微网站建设86215织梦导航网站模板
  • 大学计算机基础(Windows 7+Office 2010)第七章课后练习
  • 百度收录删除旧网站什么是网络营销策划书
  • 数据库作业5
  • 完整网站源码asp谷歌下载安装
  • 怎么仿一个复杂的网站网站的建设与维护步骤