天天看点

状态机设计原理及c语言实现一.简介二.使用状态机思路实现密码输入三.总结

文章目录

  • 一.简介
    • 1.什么是状态机?
    • 2.两种状态机模型:more型和mealy型
    • 3.状态机解决了什么问题?
    • 4.状态机设计核心思路
  • 二.使用状态机思路实现密码输入
    • 1.设计要求
    • 2.设计思路分析
    • 3.c语言代码实现
    • 4.测试结果:
  • 三.总结

一.简介

1.什么是状态机?

  有限状态机:常说的状态机就是有限状态机FSM。FSM指的是有有限个状态,这个机器能够从外部接收信号和信息输入,机器在接收到外部输入的信号后会综合考虑当前自己的状态和用户输入的信息,然后机器做出动作并跳转到另一个状态。例如:水(当前状态)------->加热(输入信息)------->水蒸气(跳转的另一个状态)

因此状态改变需要考虑两个因素:<1>当前状态 <2>外部输入

2.两种状态机模型:more型和mealy型

  more型状态机的特点是:输出状态只和当前状态有关(与输入信号无关)。就好比0和1互斥的关系,状态只能在0和1之间转换,从0状态只能变到1状态。

  mealy型状态机的特点是:输出状态不仅和输入状态有关,还和输入信号有关(不同的激励有不同的结果)。状态机会综合考虑当前状态和输入信号两个条件来决定接下来的输出状态。

3.状态机解决了什么问题?

  我们写的程序大都是顺序执行的,但是外部不一定会按照既定的流程来给程序输入信息,而程序还需要完全能够接收并响应外部的这些输入信号,还要做出准确的相应动作。

4.状态机设计核心思路

  在正确的状态下执行正确的操作,状态会向前推进。

二.使用状态机思路实现密码输入

1.设计要求

  密码为123456,必须连续正确输入123456六个数才会解锁成功,中途出错就会恢复到起始状态。

2.设计思路分析

  这里使用状态机来实现,也就是一共有STATE0------->STATE6七个状态,初始状态为STATE0,在当前状态下输入正确则推动状态跳转到下一个状态,当前状态下输入错误则恢复到STATE0状态。状态机设计核心要点:当前状态+驱动条件。也就是必须在正确的状态下有正确的输入才会跳转到下一个状态。当状态条状到STATE6表示密码输入正确。

3.c语言代码实现

#include<stdio.h>
/*
状态机实现密码输入
要求:密码为123456,必须连续输入正确123456六个数才会解锁成功,中途出错就会恢复到起始状态。
这里使用状态机来实现,也就是一共有STATE0------->STATE6七个状态,初始状态为STATE0,在当前状态下输入正确则推动状态跳转到下一个状态,
当前状态下输入错误则恢复到STATE0状态。
状态机设计核心要点:当前状态+驱动条件。也就是必须在正确的状态下有正确的输入才会跳转到下一个状态。
*/

//定义状态枚举
typedef enum
{
	STATE0,
	STATE1,
	STATE2,
	STATE3,
	STATE4,
	STATE5,
	STATE6
}state;

int main(int argc,char *argv[])
{
	int num = 0;
	state current_state = STATE0;       //定义当前状态为初始状态STATE0
	while(1)
	{
		switch(current_state)
		{
			case STATE0:     //设计核心1:当前状态
				scanf("%d",&num);
				if(num == 1) //设计核心2:当前状态下的驱动条件成立
				{
					current_state = STATE1;  //输入条件成立,跳转到下一状态
				}
				else{
					current_state = STATE0;  //输入条件不成立,恢复初始状态
				}
			break;
			case STATE1:     //核心1:当前状态
				scanf("%d",&num);
				if(num == 2) //核心2:当前状态下的驱动条件成立
				{
					current_state = STATE2;  //输入条件成立,跳转到下一状态
				}
				else{
					current_state = STATE0;  //输入条件不成立,恢复初始状态
				}
			break;
			case STATE2:     //核心1:当前状态
				scanf("%d",&num);
				if(num == 3) //核心2:当前状态下的驱动条件成立
				{
					current_state = STATE3;  //输入条件成立,跳转到下一状态
				}
				else{
					current_state = STATE0;  //输入条件不成立,恢复初始状态
				}
			break;			
			case STATE3:     //核心1:当前状态
				scanf("%d",&num);
				if(num == 4) //核心2:当前状态下的驱动条件成立
				{
					current_state = STATE4;  //输入条件成立,跳转到下一状态
				}
				else{
					current_state = STATE0;  //输入条件不成立,恢复初始状态
				}
			break;	
			case STATE4:     //核心1:当前状态
				scanf("%d",&num);
				if(num == 5) //核心2:当前状态下的驱动条件成立
				{
					current_state = STATE5;  //输入条件成立,跳转到下一状态
				}
				else{
					current_state = STATE0;  //输入条件不成立,恢复初始状态
				}
			break;	
			case STATE5:     //核心1:当前状态
				scanf("%d",&num);
				if(num == 6) //核心2:当前状态下的驱动条件成立
				{
					current_state = STATE6;  //输入条件成立,跳转到下一状态
				}
				else{
					current_state = STATE0;  //输入条件不成立,恢复初始状态
				}
			break;
			default:break;
		}
		//每次输完判断状态是否跳转到STATE6
		if(current_state == STATE6)
		{
			printf("密码输入正确,开锁成功\r\n");
			break;
		}
	}
	return 0;
}
           

4.测试结果:

43
4
31
1
2
3
43
1
2
3
4
5
6
密码输入正确,开锁成功
           

可以看出必须连续输入123456正确才能开锁成功。

三.总结

  状态机设计记住两个核心要点:当前状态+输入条件。只有状态和输入条件匹配才会推动状态机跳转到下一状态。抓住这一设计思想状态机就真正理解了。

继续阅读