C++(42)-FSM-有限状态机

news/2024/4/27 5:02:51/文章来源:https://blog.csdn.net/aggie4628/article/details/129137912

1.FSM 是什么?
     一种用来进行对象行为建模的工具,用于描述对象在生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。
2.FSM 组成:状态、事件、动作
3.FSM类型:
  3.1Moore: 输出:当前状态有关
                              输入事件无关
  3.2Mealy: 输出:当前状态有关
                             输入事件有关

4.FSM应用:TCP协议状态机
5.示例-穷举法
6.示例-查表法
7.示例-无线通信协议状态机
8.示例-IPSec 加密状态机

 


语法
1.enmu
   1.1限定作用域: 关键字:class struct

//1.定义
enum class color
{RED,GREEN,BLUE
};

1.2不限定作用域

	enum color{RED,GREEN,BLUE};

解决重名的问题。

//1.定义两种枚举enum class color_inner{RED,GREEN,BLUE};enum color_out{RED,GREEN,BLUE};//2.声明并赋值
color_inner colorinner = RED;              //错误
color_inner colorinner = color_inner::RED; //正确color_out colorout = RED;                  //正确
color_out colorout = color_out::RED;       //正确

2.STRUCT
2.1结构体

    struct 结构体名 变量名
    struct 结构体名 变量名 = { 成员1值 , 成员2值…}
    定义结构体时创建变量
 

struct student
{string name;int age;int score;   
}stu3;int main(){//结构体变量创建方式1: struct 结构体名 变量名struct student stu1;stu1.name = "七喜";stu1.age = 20;stu1.score = 95;//结构体变量创建方式2: struct 结构体名 变量名 = { 成员1值 , 成员2值…}struct student stu2 = {"可乐",19,100};//结构体变量创建方式3:stu3.name = "雪碧";stu3.age  = 20;stu3.score = 90;return 0;
}

2.2结构体数组
     struct 结构体名 数组名[元素个数] = { { } , { } ,…, { } }
    

struct student
{string name;int age;int score;   
};int main(){//结构体数组struct student stus[3] = {{"康师傅",20,95},{"百事",19,100},{"农夫山泉",20,90};
}

2.3

//C:1.struct- 无结构名字
// 变量在结尾声明 直接用
struct 
{string name;int age;int score;   
} s1;//2.struct+结构名字
// 变量新声明
struct STUDENT{member-list};
STUDENT st1,st2[10],*st3;//3. struct 前+ typedef创建新类型声明 结构名字在最后
//  变量新声明 
typedef struct
{string name;int age;int score; 
} STUDENT;


5.示例-穷举法示例
  

//状态定义
typedef enum{STATE1=0,STATE2,STATE3,STATE4,STATE5,STATE6,STATE7,
}STATE;void CFsmDemoDlg::OnBnClickedexhaustion()
{//current_state:状态机的当前状态 //                初始状态为STATE1int num = 0;STATE current_state = STATE1;printf("请输入密码,密码正确开锁,\n");while (1){scanf("%d", &num);printf("num=%d \n", num);switch (current_state){case STATE1:if (num == 1)current_state = STATE2;     // 用户输入对了一步,STATE走一步elsecurrent_state = STATE1;break;case STATE2:if (num == 2)current_state = STATE3;   // 用户输入对了一步,STATE走一步elsecurrent_state = STATE1;break;case STATE3:if (num == 3)current_state = STATE4;   // 用户输入对了一步,STATE走一步elsecurrent_state = STATE1;break;case STATE4:if (num == 4)current_state = STATE5;   // 用户输入对了一步,STATE走一步elsecurrent_state = STATE1;break;case STATE5:if (num == 5)current_state = STATE6;   // 用户输入对了一步,STATE走一步elsecurrent_state = STATE1;break;case STATE6:if (num == 6)current_state = STATE7;   // 用户输入对了一步,STATE走一步elsecurrent_state = STATE1;break;default:current_state = STATE1;}if (current_state == STATE7){printf("锁开了 \n");break;}}
}


6.示例-查表法示例


6.1状态、事件、动作声明
 

//1.状态
typedef enum {STATE_1=0,STATE_2,STATE_3,STATE_4,STATE_5,STATE_6,STATE_7
}FSM_STATES;
//2.事件
typedef enum {EVENT_1 = 0,EVENT_2,EVENT_3,EVENT_4,EVENT_5,EVENT_6
}FSM_EVENTS;
//3.动作
void action_func(int state)
{printf("current state %d\n",state);
}
#define STATE_NUM 7
#define EVENT_NUM 6
struct MY_FSM
{void(*action)(int);int next_state;
};//查的就是这张表
MY_FSM my_fsm[STATE_NUM][EVENT_NUM]=
{{//STATE_1{action_func, STATE_2},//event_1},{//STATE_2{action_func, STATE_1},//event_1{action_func, STATE_3},//event_2},{//STATE_3{action_func, STATE_1},//event_1{action_func, STATE_1},//event_2{action_func, STATE_4},//event_3},{//STATE_4{action_func, STATE_1},//event_1{action_func, STATE_1},//event_2{action_func, STATE_1},//event_3{action_func, STATE_5},//event_4},{//STATE_5{action_func, STATE_1},//event_1{action_func, STATE_1},//event_2{action_func, STATE_1},//event_3{action_func, STATE_1},//event_4{action_func, STATE_6},//event_5},{//STATE_6{action_func, STATE_1},//event_1{action_func, STATE_1},//event_2{action_func, STATE_1},//event_3{action_func, STATE_1},//event_4{action_func, STATE_1},//event_5{action_func, STATE_7},//event_6},};


6.2 运行
 

int main()
{int state = STATE_1;                       //1.初始状态int event;while (1)                                  //2.循环处理{scanf("%d", &event);printf("event =%d \n", event);event--;if (state == STATE_4){printf("锁开了,\n");}(*(my_fsm[state][event].action))(state); //3.修改此处的数据state = my_fsm[state][event].next_state;}
}


7.示例-无线通信协议状态机
    很复杂的一张图,我也没看懂。


7.1数据
 

//1.状态转换数据库
typedef struct _state_trans_data
{State cur_state;   //当前状态Event event;       //事件IDState next_state;  //下一个状态action act_func;   //收到事件后的动作
}state_trans_data_t;//2.
tyedef struct _state_machine
{State real_state;              //实际状态int trans_num;                 //状态转换数state_trans_data_t * st_data;   //指向状态转换数据库
}state_machine_t;//3.
static state_trans_data_t st_db[] = 
{ {S1,E3,S2,f12},{S1,E4,S2,NULL},{S2,E1,S3,f23},{S2,E4,S2,f22},{S3,E2,S1,f31},{S3,E3,S2,f32},{S3,E5,S3,f33}	
};
//4.测试:事件驱动
static Event input_event[15] =
{E1,E2,E3,E4,E5,E1,E2,E3,E4,E5,E1,E2,E3,E4,E5
};


7.2 运行
 

void main(state_machine_t *pSM,Event evt)
{state_trans_data_t* st_db = NULL;st_db = find_st_data(psm, evt);if (!st_db){printf("current state =%d ignore count: %d\n",psm->real_state,evt);return;}pSM->real_state = st_db->next_state;action act_func = st_db->act_func;if (!act_func){printf("next state %d no action \n", pSM->real_state);}act_func(evt);state_machine_t sm;sm.eal_state = S1;sm.trans_num = ARRAY_SIZE(st_db);sm.st_data = st_db;return;
}



8.示例-IPSec 加密状态机

 8.1数据
   

struct XMIT_STATE {enum ipsec_xmit_value(*action)(struct ipsec_xmit_state* ixs);int next_state;
};
XMIT_STATE xmit_state_table[] = {
[IPSEC_XSM_INIT1]        = {ipsec_xmit_init1,      IPSEC_XSM_INIT2 },
[IPSEC_XSM_INIT2]        = {ipsec_xmit_init2,      IPSEC_ENCAP_INIT },
[IPSEC_XSM_ENCAP_INIT]   = {ipsec_encap_init,      IPSEC_ENCAP_SELECT },
[IPSEC_XSM_ENCAP_SELECT] = {ipsec_encap_select,    IPSEC_XSM_DONE },
[IPSEC_XSM_ESP]          = {ipsec_xmit_esp,        IPSEC_ESP_AH },
[IPSEC_XSM_ESP_AH]       = {ipsec_xmit_esp_ah,     IPSEC_XSM_CONT },
[IPSEC_XSM_AH]           = {ipsec_xmit_ah,         IPSEC_XSM_CONT },
[IPSEC_XSM_IPIP]         = {ipsec_xmit_ipip,       IPSEC_XSM_CONT },
[IPSEC_XSM_IPCOMP]       = {ipsec_xmit_ipcomp,     IPSEC_XSM_CONT },
[IPSEC_XSM_CONT]         = {ipsec_xmit_cont,       IPSEC_XSM_DONE },
[IPSEC_XSM_DONE]         = {NULL,                  IPSEC_XSM_DONE }};


 8.2运行
 

void ipxec_xsm(struct ipsec_xmit_state* lxs)
{enum ipsec_xmit_value stat = IPSEC_XMIT_DNCAPFAIL;unsigned more_allowed;if (lxs == NULL)return;more_allowed = 1000;while (lxs->state != IPSEC_XSM_DONE && --more_allowed){lxs->next_state = xmit_state_table[lxs->state].next_state; //数据stat = xmit_state_table(lxs->state).action(ixs);if (stat == IPSEC_XMIT_OK){lxs->state = lxs->next_state;}else if (state ==IPSEC_XMIT_DENDING){return;}else{lxs->state = IPSEC_XSC_DONE;}}lxs->xsm_complete(lxs, stat);}


 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_72172.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql -学习总结

mysql 详解1、mysql特点2、事务2.1 事务的四大特性 – ACID2.2 并发事务问题2.3 事务的四大隔离级别2.4 事务隔离级别操作sql2.5 事务原理 – LBCC MVCC2.4.1 行的隐藏列2.4.2 ReadView2.4.3 MVCC在四种隔离级别下的区别2.5 undo log、binlog、redo log2.5.1 Undo log2.5.2 bin…

2023年2月22日PMP®项目管理认证课程正式开课

PMP认证是Project Management Institute在全球范围内推出的针对评价个人项目管理知识能力的资格认证体系。国内众多企业已把PMP认证定为项目经理人必须取得的重要资质。 PMP认证是Project Management Institute在全球范围内推出的针对评价个人项目管理知识能力的资格认证体系。…

安装MQTT Server遇到报错“cannot verify mosquitto.org‘s certificate”,该如何解决?

MQTT是基于发布/订阅的轻量级即时通讯协议,很适合用于低带宽、不稳定的网络中进行远程传感器和控制设备通讯等操作中。在我们的软件研发中,也经常使用MQTT协议进行消息通信等。今天来和大家分享一些关于在安装MQTT Server中遇到的疑难问题及解决思路。当…

文献综述怎么写?有哪些准备工作和内容要求

文献综述的撰写是提高研究生论文写作能力的重要途径,是研究生在撰写学术论文和学位论文中必须要涉及的内容,是不可或缺的,写好一篇好的文献综述是存在诸多困难和挑战的,需要掌握一定的技巧和方法。 一、文献综述的写作目的 文献综…

mysql常用且易混淆函数整理

DATE_FORMAT(date,format) 函数中format的格式如下: 类型转化函数 为了进行数据类型转化,MySQL提供了CAST()函数,它可以把一个值转化为指定的数据类型。类型有:BINARY,CHAR,DATE,TIME,DATETIME,SIGNED,UNSIGNED 示例&a…

Python|每日一练|数组|回溯|栈|树|双指针|单选记录:N 皇后|二叉树的前序遍历|四数之和

1、N 皇后(数组,回溯) n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。 每一种解法包含一个不同的 n 皇后问题 …

操作系统真相还原_第6章:完善内核

文章目录6.1 函数调用约定简介6.2 汇编语言和C语言混合编程汇编调用CC调用汇编6.3 实现打印函数流程程序编译并写入硬盘执行6.4 内联汇编简介汇编语言AT&T语法基本内联汇编扩展内联汇编6.1 函数调用约定简介 调用约定: calling conventions 调用函数时的一套约…

「mysql是怎样运行的」第5章 盛放记录的大盒子---InnoDB数据页结构

「mysql是怎样运行的」第五章 盛放记录的大盒子—InnoDB数据页结构 文章目录「mysql是怎样运行的」第五章 盛放记录的大盒子---InnoDB数据页结构[toc]一、不同类型的页介绍二、数据页结构的快速浏览三、记录在页中的存储记录头信息的秘密四、Page Directory(页目录)五、Page He…

在ONLYOFFICE中借助ChatGPT一键创建招聘启事的内容

大家好,相信和多人都在生活中或工作中看到过招聘启示,或多或少都会有些了解。今天教大家在ONLYOFFICE中怎样通过chetGPT创建一份满意的招聘启示,下面是我用chatgpt制作的一份招聘信息,请大家看一下。 ONLYOFFICE ONLYOFFICE文档是…

(HP)新手引导使用react-shepherd

1,官方参数文档:https://shepherdjs.dev/docs/tutorial-02-usage.html 2,基本代码 import { ShepherdTour } from react-shepherd; import ./index.less; // 自己的样式文件,用来修改样式 import ./shepherd.less; // 将shephe…

C++性能白皮书

最近看完了《C性能白皮书》,这本书列出了一些性能优化的思路,不过只是一些指引,没有讲具体细节,我整理出了其中的关键点分享给大家: 硬件篇 作为一个程序员,想要性能优化,最好要了解些硬件&…

为什么redis的zset用跳跃表而不用b+ tree?

这两天有小伙伴问我一个问题,为什么redis的zset用跳跃表,不用b tree? 我先不说结论,我先说下 跳跃表 和Btree 。 跳跃表 在之前的 《redis源码阅读-zset》 中,已经详解了zset的使用跳跃表的源码,今天借用…

hadoop3.*集群搭建,小白必看

hadoop广义上讲是一个大数据生态圈,接受大量处理、处理大量数据的一个全套的框架!hadoop3.x版本以后,主要有三大模块,HDFS、YARN、mapReduce这三大核心组成!什么是HDFS?分布式文件系统,hadoop集群的功能类…

数值方法笔记4:插值、近似和拟合

1. 插值1.1 插值的一些概念1.1.1 插值的定义1.1.2 插值的存在性1.1.3 插值的误差分析1.2 拉格朗日插值(Lagrange Interpolation)1.2.1 拉格朗日插值误差分析1.3 Newton多项式插值1.3.1 Newton多项式插值误差分析1.4 Chebyshev多项式确定插值点1.4.1 Chebyshev多项式性质1.5 有理…

内存映射(1)

内存映射 将磁盘文件中的数据映射到内存,用户通过修改内存就能修改磁盘文件 相关的系统调用: void *mmap() 功能:将一个文件或设备的数据映射到内存中 参数: void *addr : NULL 由内核指定length : 要映射的数据长度,…

JUC并发编程——进程与线程

目录一、进程和线程的概念1.1 进程1.2 线程1.3 进程与线程对比二、并行和并发的概念三、线程基本应用3.1 多线程应用——异步调用一、进程和线程的概念 1.1 进程 ● 程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至 …

【Mysql系列】Mysql之ACID实现原理

ACID 原子性 事务不可分割,要么全部执行,要么都不执行。原理是使用undo log。undo log,当事务对数据库进行修改的时候,会生成对应的undo log。 持久性 事务提交后,对于数据库的改变是永久性的。实现原理通过redo l…

超详细解读!数据库表分区技术全攻略

更多内容可以关注微信公众号:老程序员刘飞 分区的定义 分区是一种数据库优化技术,它可以将大表按照一定的规则分成多个小表,从而提高查询和维护的效率。在分区的过程中,数据库会将数据按照分区规则分配到不同的分区中&#xff0…

排序算法-java实现

文章目录冒泡排序选择排序插入排序快速排序希尔排序冒泡排序 原理: 依次比较两个相邻的元素,如果它们顺序错误就把它们交换过来。 时间复杂度: 若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数C和记录移…

graphviz:实现图文件的可视化

1. graphviz下载安装 参考的是这篇文章:https://blog.csdn.net/qq_37085158/article/details/126421102 graphviz的下载地址为:https://graphviz.org/download/ 2. graphviz的使用步骤 将edge文件转化成dot文件WinR,输入cmd,在…