有限状态机的两种写法

看过类似的文章,加上自己的理解,记录一下。

假设状态机的状态转换由下表所示:

状态转换表

当前状态State0State1State2事件
 action0/state1action1/state2action3/state0event0
 action4/state1  event1
 action5/state2action6/state0 event2

简单讲一下状态转换过程:当处于State0时发生event0 则执行action0并将状态变成state1,当state1状态下发生event2则执行action6并将状态变成state2。以此类推。

下面描述下实现上述状态机的两种不同的写法:

1)竖着写:在状态中判断事件,并执行相应的操作,完成相应的状态转换。

2)横着写:在事件中根据当前的状态,执行相应的操作,完成相应的状态转换。

两种写法的实现C代码:

//竖着写
switch(cur_state)
{
  case State0:
         if(event1)
          {
             action0;
             cur_state = State1;
           }
          else if(event2)
          {
              action4;
              cur_state = State1;
          }
          else if(event3)
          {
              action5;
              cur_state = State2;
          }
       break;
    case State1:
         if(event1)
          {
             action1;
             cur_state = State2;
           }
          else if(event3)
          {
              action6;
              cur_state = State0;
          }
        break;
     case State2:
         if(event1)
          {
             action3;
             cur_state = State0;
           }
        break;
     default:break;
}
//横着写
void event0func(void)
{
    switch(cur_state)
    {
        case State0:
             action0;
             cur_state = State1;
        break;
         case State1:
             action1;
             cur_state = State2;
        break;
         case State2:
             action1;
             cur_state = State0;
        break;
        default:break;
    }
}

void event1func(void)
{
    switch(cur_state)
    {
        case State0:
             action4;
             cur_state = State1;
        break;
        default:break;
    }
}

void event2func(void)
{
    switch(cur_state)
    {
        case State0:
             action5;
             cur_state = State2;
        break;
         case State1:
             action6;
             cur_state = State0;
        break;
        default:break;
    }
}

上述两种写法实现的功能完全相同,对比两种写法:

1)写法1(竖着写)使用了if -else if语句隐含了优先级,破坏可事件间的原有关系(各个时间应该同优先级)

2)写法1(竖着写)在结构上是顺序查询方式(查询事件),浪费大量的时间,而且时间不可估算。

     写法2(横着写)因为在某个时间点上状态是唯一确定的,在时间处理函数中通过switch语句可直接定位到相同状态,

     执行时间也可以估算。

3)写法2(横着写)比较直观,程序执行效率较高。

总体来说:写法2要优于写法1。

点赞