第二周作业
当前状态 |
S0 |
S1 |
事件 |
|
A0/S1 |
- |
E0 |
- |
A1/S0 |
E1 |
S0:禁止通行
S1:允许通行
E0:汽车进入门禁系统(入闸传感器变为true)
E1:汽车离开门禁系统(出闸传感器变为true)
A0:起落杆上升,通行灯变为绿灯
A1:起落杆下降,通行灯变为红灯
竖着写(在状态中判断事件)C代码片段:
cur_state = nxt_state; switch(cur_state) //在当前状态中判断事件 { case s0: //在s0状态 if(sensor==ture) //如果发生e0事件,那么就执行a0动作,并保持状态不变; {
Rod.raise();//执行a0动作; nxt_state = s1; } else { break; } case s1: //在s1状态 if(sensor==false) //如果发生e2事件,那么就执行a2动作,并将状态转移到s2态; { Rod.down();//执行a2动作; nxt_state = s0; } else { break; } }
横着写(在事件中判断状态)C代码片段:
//e0事件发生时,执行的函数
void e0_event_function(int * nxt_state)
{
int cur_state;
cur_state = *nxt_state;
switch(cur_state)
{
case s0: rod.raise();//执行a0动作;
*nxt_state = s1;
}
}
//e1事件发生时,执行的函数
void e1_event_function(int * nxt_state)
{
int cur_state;
cur_state = *nxt_state;
switch(cur_state)
{
case s1: Rod.down();//执行a2动作;
*nxt_state = s0;
}
}
引用自http://kb.cnblogs.com/page/528972/的总结
上面横竖两种写法的代码片段,实现的功能完全相同,但是,横着写的效果明显好于竖着写的效果。理由如下:
1、竖着写隐含了优先级排序(其实各个事件是同优先级的),排在前面的事件判断将毫无疑问地优先于排在后面的事件判断。这种if/else if写法上的限制将破坏事件间原有的关系。而横着写不存在此问题。
2、由于处在每个状态时的事件数目不一致,而且事件发生的时间是随机的,无法预先确定,导致竖着写沦落为顺序查询方式,结构上的缺陷使得大量时间被浪费。对于横着写,在某个时间点,状态是唯一确定的,在事件里查找状态只要使用switch语句,能一步定位到相应的状态,延迟时间可以预先准确估算。而且在事件发生时,调用事件函数,在函数里查找唯一确定的状态,并根据其执行动作和状态转移的思路清晰简洁, 效率高,富有美感。
总之,我个人认为,在软件里写状态机,使用横着写的方法比较妥帖。
竖着写的方法也不是完全不能使用,在一些小项目里,逻辑不太复杂,功能精简,同时为了节约内存耗费,竖着写的方法也不失为一种合适的选择。