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

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:状态机的当前状态 
	//                初始状态为STATE1
	int 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走一步
			   else
				   current_state = STATE1;
			   break;
			case STATE2:
				if (num == 2)
					current_state = STATE3;   // 用户输入对了一步,STATE走一步
				else
					current_state = STATE1;
				break;
			case STATE3:
				if (num == 3)
					current_state = STATE4;   // 用户输入对了一步,STATE走一步
				else
					current_state = STATE1;
				break;
			case STATE4:
				if (num == 4)
					current_state = STATE5;   // 用户输入对了一步,STATE走一步
				else
					current_state = STATE1;
				break;
			case STATE5:
				if (num == 5)
					current_state = STATE6;   // 用户输入对了一步,STATE走一步
				else
					current_state = STATE1;
				break;
			case STATE6:
				if (num == 6)
					current_state = STATE7;   // 用户输入对了一步,STATE走一步
				else
					current_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;       //事件ID
	State 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);

}


 

 

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值