C语言有效状态自动机,用C语言实现有限状态自动机FSM

摘要:状态机模式是一种行为模式,在《设计模式》这本书中对其有详细的描述,通过多态实现不同状态的调转行为的确是一种很好的方法,只可惜在嵌入式环境下,有时只能写纯C代码,并且还需要考虑代码的重入和多任务请求跳转等情形,因此实现起来着实需要一番考虑。本文主要为你实现一个简单的有限状态机,没有考虑代码的重入和多任务跳转,为以后复杂的状态机实现,打下基础。

本文来源:用C语言实现有限状态自动机FSM

一、状态机实现的要素

首先,分析一下一个普通的状态机究竟要实现哪些内容。

状态机存储从开始时刻到现在的变化,并根据当前输入,决定下一个状态。这意味着,状态机要存储状态、获得输入(我们把它叫做跳转条件)、做出响应。

0818b9ca8b590ca3270a3433284dd417.png

如上图所示,{s1, s2, s3}均为状态,箭头c1/a1表示在s1状态、输入为c1时,跳转到s2,并进行a1操作。

最下方为一组输入,状态机应做出如下反应:

当前状态

输入

下一个状态

动作

s1

c1

s2

a1

s2

c2

s3

a2

s3

c1

s2

a3

s2

c2

s3

a2

s3

c1

s2

a3

s2

c1

s_trap

a_trap

s_trap

c1

s_trap

a_trap

当某个状态遇到不能识别的输入时,就默认进入陷阱状态,在陷阱状态中,不论遇到怎样的输入都不能跳出。

为了表达上面这个自动机,我们定义它们的状态和输入类型:

总结一下,我们需要定义的有状态、输入、行为(动作+下一个状态),其中,行为的个数是“状态数*输入数量”(其中有一些是重复的);其中动作一般来说可以用一个函数指针来实现。

二、具体设计

在嵌入式环境中,由于存储空间比较小,因此把它们全部定义成宏。此外,为了降低执行时间的不确定性,我们使用O(1)的跳转表来模拟状态的跳转。

首先定义跳转类型:

然后按照上图中的跳转关系,把三个跳转加一个陷阱跳转先定义出来:

其中的动作,由用户自己完成,在这里仅定义一条输出语句。

即可表达上文中的跳转关系。

最后定义状态机,如果不考虑多任务请求,那么状态机仅需要存储当前状态便行了。例如:

总结:我们现在设计实现好了一个状态机,然后要给这个状态机特定的输入,看看状态机的运转情况,以上面图中的那个状态机为例,我们输入的序列是0和1分别代表c1和C2,然后状态s1,s2分别对应0,1.用程序实现这个内容如下

三、程序实现

程序清单:小型状态机的实现

#include

#include

#include

typedefintstate;

typedefintcondition;

#define STATENUM 4

#define STATE1 0

#define STATE2 1

#define STATE3 2

#define STATETRAP 3

#define CONDITIONS 2

#define CONDITION1 0

#define CONDITION2 1

typedefvoid(* actiontype)(state mystate,condition mycondition);

typedefstruct{

state next;

actiontype action;

}trasition, *ptrasition;

voidaction1(state mystate,condition myconditon);

voidaction2(state mystate,condition myconditon);

voidaction3(state mystate,condition myconditon);

voidactiontrap(state mystate,condition myconditon);

trasition t1={

STATE2,action1

};

trasition t2={

STATE3,action2

};

trasition t3={

STATE2,action3

};

trasition tt={

STATETRAP,actiontrap

};

voidaction1(state mystate,condition myconditon){

printf("action1 one triggered\n");

}

voidaction2(state mystate,condition myconditon){

printf("action2 one triggered\n");

}

voidaction3(state mystate,condition myconditon){

printf("action3 one triggered\n");

}

voidactiontrap(state mystate,condition myconditon){

printf("actiontrap one triggered\n");

}

ptrasition transition_table[STATENUM][CONDITIONS] = {

/*      c1,  c2*/

/* s1 */&t1, &tt,

/* s2 */&tt, &t2,

/* s3 */&t3, &tt,

/* st */&tt, &tt,

};

typedefstruct

{

state current;

} StateMachine, * pStateMachine;

state step(pStateMachine machine, condition mycondition)

{

ptrasition t = transition_table[machine->current][mycondition];

(*(t->action))(machine->current, mycondition);

machine->current = t->next;

printf("the current state is %d\n",t->next );

returnmachine->current;

}

intmain(intargc,char*argv[])

{

StateMachine mymachine;

mymachine.current=STATE1;

intmycon;

charch;

while(1){

scanf("%d",&mycon);

step(&mymachine,mycon);

}

return0;

}

程序输入与输出结果示例:

0818b9ca8b590ca3270a3433284dd417.png

四、外部参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include int main() { int state_key = 1; //钥匙状态 为1时钥匙区有钥匙,为时钥匙区 无钥匙 int state_hold = 0; // 钥匙持有状态 为1时持有钥匙,为时 未持有钥匙 int state_door = 0; //门状态 0:关闭 1:打开 int state_lock = 1; //上锁状态 1:上锁 0:解锁 int order; // 用于存放用户输入指令 printf("this is a game.\n"); printf ("if you want to OPEN THE DOOR ,input 1\n"); printf ("if you want to CLOSE THE DOOR ,input 2\n"); printf ("if you want to LOCK THE DOOR ,input 3\n"); printf ("if you want to UNLOCK THE DOOR,input 4\n"); // printf ("if you want to LOCK THE DOOR ,input 5\n"); printf("please input the order\n"); while(1) { scanf("%d",&order); // if(order!=(1||2||3||4)) // { // printf("worng input ,please input again.\n"); // continue; // } switch(order) { case 1 : if(state_door==1) { printf("the door has been opened before\n"); break; } if(state_lock==1) { printf("the door has been lock\n"); break; } state_door=1; break; case 2: if(state_door==0) { printf("the door has been closed before\n"); break; } if(state_lock==1) { printf("the door has been lock\n"); break; } state_door=0; break; case 3: if(state_door==1) { printf("the door has been opened before\n"); break; } if(state_lock==1) { printf("the door has been lock\n"); break; } state_lock=1; break ; case 4: if(state_door==1) { printf("the door has been opened before\n"); break; } if(state_lock==0) { printf("the door has not been lock\n"); break; } state_lock=0; break ; } } }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值