状态机编程.docx
《状态机编程.docx》由会员分享,可在线阅读,更多相关《状态机编程.docx(15页珍藏版)》请在冰豆网上搜索。
状态机编程
状态机编程(转)
【转载1】有限状态机的实现
有限状态机(FiniteStateMachine或者FiniteStateAutomata)是软件领域中一种重要的工具,很多东西的模型实际上就是有限状态机。
最近看了一些游戏编程AI的材料,感觉游戏中的AI,第一要说的就是有限状态机来实现精灵的AI,然后才是A*寻路,其他学术界讨论比较多的神经网络、模糊控制等问
题还不是很热。
FSM的实现方式:
1)switch/case或者if/else
这无意是最直观的方式,使用一堆条件判断,会编程的人都可以做到,对简单小巧的状态机来说最合适,但是毫无疑问,这样的方式比较原始,对庞大的状态机难以维护。
2)状态表
维护一个二维状态表,横坐标表示当前状态,纵坐标表示输入,表中一个元素存储下一个状态和对应的操作。
这一招易于维护,但是运行时间和存储空间的代价较大。
3)使用StatePattern
使用StatePattern使得代码的维护比switch/case方式稍好,性能上也不会有很多的影响,但是也不是100%完美。
不过RobertC.Martin做了两个自动产生FSM代码的
工具,forjava和forC++各一个,在
Pattern的代码,这样developer的工作只需要维护状态机的文本描述,每必要冒引入bug的风险去维护code。
4)使用宏定义描述状态机
一般来说,C++编程中应该避免使用#define,但是这主要是因为如果用宏来定义函数的话,很容易产生这样那样的问题,但是巧妙的使用,还是能够产生奇妙的效果。
MFC就是使用宏定义来实现大的架构的。
在实现FSM的时候,可以把一些繁琐无比的if/else还有花括号的组合放在宏中,这样,在代码中可以3)中状态机描述文本一样写,通过编译器的预编译处理产生1)一
样的效果,我见过产生C代码的宏,如果要产生C++代码,己软MFC可以,那么理论上也是可行的。
【评】:
状态表的实现方法,《C专家编程》第8章有具体说明,转载【6】
☆──────────────────────传说中的分隔符──────────────────────────────☆
来源2:
【转载2】有限状态机的c实现
2007-05-1115:
12
網絡上可以搜索到很多有限狀態機的代碼和理論分析,這兒僅僅是做一個簡單的例子,僅供入門參考。
这儿以四位密码校验作为状态机的例子,连续输入2479就可以通过密码测试。
一个非常简单的例子,在实际的状态机实例中,状态转移表要更復雜一些,不過方式非常
類似。
在狀態查詢的地方可以做優化,同時對于輸入量也可以做有效性優化。
具體代碼如下:
viewplaincopytoclipboardprint?
c.h
typedefenum{
STATE1=1,
STATE2,
STATE3,
STATE4,
STATE5,//passwordpass
//...ADDhere
}STATE;
INPUT1='2',
INPUT2='4',
INPUT3='7',
INPUT4='9',
}INPUT;
typedefstruct
{
STATEcur_state;
INPUTinput;
STATEnext_state;
}STATE_TRANS;
c.c
#include
#include"c.h"
STATE_TRANSstate_trans_arry[]=
{STATE1,INPUT1,STATE2},
{STATE2,INPUT2,STATE3},
{STATE3,INPUT3,STATE4},
{STATE4,INPUT4,STATE5},
};
#defineSTATE_TRANS_CNT(sizeof(state_trans_arry)/sizeof(state_trans_arry[0]))
intmain()
inti;
charch;
STATEstate_machine=STATE1;
while(ch!
='e')
ch=getchar();
if((ch>='0')&&(ch<='9'))//fordigitpasswordinputonly
for(i=0;i { if((ch==state_trans_arry[i].input)&&(state_machine==state_trans_arry[i].cur_state)) { state_machine=state_trans_arry[i].next_state; continue; } elseif(i==(STATE_TRANS_CNT-1))//notransfermatch,resetstate { state_machine=STATE1; } } if(state_machine==STATE5) printf("Passwordcorrect,statetransfermachinepass!\n"); } } return0; } c.c#include #include"c.h"STATE_TRANSstate_trans_arry[]={{STATE1,INPUT1,STATE2},{STATE2,INPUT2,STATE3},{STATE3,INPUT3,STATE4},{STATE4,INPUT4,STATE5},};#defineSTATE_TRANS_CNT(sizeof(state_trans_arry)/sizeof(state_trans_arry[0]))intmain() {inti;charch;STATEstate_machine=STATE1;while(ch!='e'){ ch=getchar(); if((ch>='0')&&(ch<='9'))//fordigitpasswordinputonly { for(i=0;i { if((ch==state_trans_arry[i].input)&&(state_machine==state_trans_arry[i].cur_state)) { state_machine=state_trans_arry[i].next_state; //continue; break; //做了修改在vc上可以实现 } elseif(i==(STATE_TRANS_CNT-1))//notransfermatch,resetstate { state_machine=STATE1; } } if(state_machine==STATE5) printf("Passwordcorrect,statetransfermachinepass!\n"); }}return0;}☆──────────────────────传说中的分隔符──────────────────────────────☆来源3:【转载3】有限状态机自动机状态图--一个图的数据结构!1.while+switch;2.状态机:就是指定系统的所有可能的状态及状态间跳转的条件,然后设一个初始状态输入给这台机器,机器就会自动运转,或最后处于终止状态,或在某一个状态不断循环。游戏中状态切换是很频繁的。可能以前要切换状态就是if~else,或者设标志,但这些都不太结构化,如果把它严格的设为一种标准的状态机,会清楚的多。比如控制一扇门的运动,初始时门是关的,当有力作用在门上时,门开始慢慢打开,力的作用完后,门渐渐停止不动,当有反向的力时,门又渐渐关上,知道回到初始关的状态。这个你会怎么来编程实现呢。似乎很麻烦,的确,没有状态机的思想时会很烦,设很多标志,一堆if条件。用状态机的话,不只是代码更清晰,关键是更符合逻辑和自然规律,不同状态不同处理,满足条件则跳转到相关状态。伪码如下:enum { CLOSED,//关上状态 CLOSING,//正在关状态 OPENED,//打开状态 OPENING,//正在开的状态 }doorState=CLOSED;//初始为关 Update() { switch(doorState) caseCLOSED: if(有人推门) doorState=OPENING;//跳转到正在开状态 break; caseOPENING: door.Rotation+=DeltaAngle;//门的旋转量递增 if(门的速度为零)//力的作用已去 doorState=OPENED;//跳转到开状态 break; caseOPENED: if(有人关门) doorState=CLOSING; break; caseCLOSING: door.Rotation-=DeltaAngle;//门的旋转量递减 if(门的旋转角度减为零) doorState=CLOSED;//门已关上 break; } //而绘制代码几乎不用怎么变,门就是会严格按照状态机的指示去运动,该停就会停 Render() { RotateView(door.Rotation); DrawDoor(door.Position); } enum{ CLOSED,//关上状态 CLOSING,//正在关状态 OPENED,//打开状态 OPENING,//正在开的状态}doorState=CLOSED;//初始为关Update(){ switch(doorState) caseCLOSED: if(有人推门) doorState=OPENING;//跳转到正在开状态 break; caseOPENING: door.Rotation+=DeltaAngle;//门的旋转量递增 if(门的速度为零)//力的作用已去 doorState=OPENED;//跳转到开状态 break; caseOPENED: if(有人关门) doorState=CLOSING; break; caseCLOSING: door.Rotation-=DeltaAngle;//门的旋转量递减 if(门的旋转角度减为零) doorState=CLOSED;//门已关上 break;}//而绘制代码几乎不用怎么变,门就是会严格按照状态机的指示去运动,该停就会停Render(){ RotateView(door.Rotation); DrawDoor(door.Position);}这是一个简单但很典型的例子,状态机的应用太多了。就说一个基本游戏的运转:(用到了一个状态然后还有子状态)UpdateGame() BEGIN; switch(gameState) case等待选择菜单://它有三个子状态。 if(选择菜单项==开始) { 游戏初始; gameState=开始游戏 } if(选择菜单项==选项) gameState=设置 if(选择菜单项==退出) gameState=退出 case开始: 游戏运行; if(用户按退出键) gameState=等待选择菜单; ...其他的状态跳转处理; case退出: 释放资源; 退出; case设置: 分别处理不同的选项,跳转不同的子状态; case....//其他状态的处理 END; UpdateGame()BEGIN; switch(gameState) case等待选择菜单://它有三个子状态。 if(选择菜单项==开始) { 游戏初始; gameState=开始游戏 } if(选择菜单项==选项) gameState=设置 if(选择菜单项==退出) gameState=退出 case开始: 游戏运行; if(用户按退出键) gameState=等待选择菜单; ...其他的状态跳转处理; case退出: 释放资源; 退出; case设置: 分别处理不同的选项,跳转不同的子状态; case....//其他状态的处理 END; 某一个状态可以包含更多的子状态,这样最好是同一层次的状态设为一个枚举,并分到另一个switch处理如enumSTATES{state1,state2,state3};state2又包含若干状态则再定义enumSUB_STATE2{sub_state2_1,sub_state2_2,sub_state2_3,};想很多基本的渲染效果,如淡入淡出,闪烁等等,用状态的思想会事半功倍,思路也更清晰。其实像Opengl,Direct3D这样的渲染引擎本身就是状态机,当你设置渲染的状态,这台机器就保持这个状态进行渲染工作,如保持光照位置,保持片元颜色,直到你再次改变它的状态。状态机的应用实在太广,相关理论也很多,最近上课学的随机过程里也讲到一些,数字电路里的时序逻辑器件也是用状态机来描述。这些不必多说了。总之,用状态机的角度去看待问题,往往能把比较复杂的系统分解为能单独处理的众多子状态,处理也会得心应手。希望大家多用它,很好的东西。二、推荐这个:[程序员杂志2004.8月刊_state模式和composite模式实现的状态机引擎]个人感觉状态机的几个不同实现阶段:1、switch/case最原始的实现方式,是很多的c程序员习惯采用的方式。2、查找表[状态、事件、动作],稍微做了一点改进。有点类似MFC的雏形。3、在以上基础上做的一些改进或者变体。[比如用一个栈结构,激活的状态位于栈顶,自动的映射事件和动作的对应,再或者通过一些巧妙的宏等手段进行包装。但是线性结构在实际中使用比较受限、过于技巧性的宏比较难于理解...]4、面向对象的设计下、灵活运用模式。如上面给出的链接。重用性和灵活性方面都有不错的表现。沿袭类似的设计思路、根据实际开发内容进行改造后利用。【评】:伪代码部分,可以帮助很好的理解【转载1】文章中叙述的FSM的实现方法1;查找表[状态、事件、动作],稍微做了一点改进。有点类似MFC的雏形类似于【转载1】文章中叙述的FSM的实现方法2(状态表)☆──────────────────────传说中的分隔符──────────────────────────────☆【转载4】fsmimplementedinCcode(FSM状态机用C实现)用C语言实现一个状态机,很简单,和大家分享这是我做毕业设计时,用nRF24L01组建了一个简单的网络,做的一个小的状态机,网络中三个节点,开始拓扑为网状,后来为星型。#include #include #include //Finitestatemachinedeclaration //statedeclaration #defineIDLE 0//idlestateinrxmode #defineM_BROADCAST 1//broadcaststateintxmode,broadcasttobeamasterpoint #defineM_WAIT_BROADCAST_ACK 2//waitforbroadcastackstateinrxmode,waitforthepointackinaspecifictimewindow #defineM_WAIT_COMMAND 3//waitforcommandstate,waitforPCcommandviaUART #defineM_BROADCAST_CANCEL 4//broadcastcancelstate,broadcasttocancelmasterpoint #defineS_BROADCAST_ACK 5//slavemode,sendbackselfphysicaladdress #defineS_WAIT_COMMAND 6//slavemode,waitforcommandfromthemasterpoint //statetransitiontrig //usedinmastermode intisReqBeMaster=0; //IsPCrequestthepointtobemaster? intisTimeout=0; //Istimeout? intisReqCancelMaster=0; //Isrequesttocancelmaster? //usedinslavemode intisRxBroadcast=0; //Isthereapointbroadcasttobemaster? intisRxBroadcastCancel=0; //Isreceivebroadcastcancelmaster? typedefstructfsmtag { intstate;//state inttimeouttime; //timeouttimeinmilliseconds }fsm; //functionprototype intmain() { fsmf; f.state=IDLE; f.timeouttime=0; while(1) { switch(f.state) { caseIDLE: puts("IDLE\nWaitforisReqBeMaster(1/0)isRxBroadcast(1/0):"); scanf("%d%d",&isReqBeMaster,&isRxBroadcast); if(isR
if((ch==state_trans_arry[i].input)&&(state_machine==state_trans_arry[i].cur_state))
state_machine=state_trans_arry[i].next_state;
continue;
}
elseif(i==(STATE_TRANS_CNT-1))//notransfermatch,resetstate
state_machine=STATE1;
if(state_machine==STATE5)
printf("Passwordcorrect,statetransfermachinepass!
\n");
return0;
for(i=0;i { if((ch==state_trans_arry[i].input)&&(state_machine==state_trans_arry[i].cur_state)) { state_machine=state_trans_arry[i].next_state; //continue; break; //做了修改在vc上可以实现 } elseif(i==(STATE_TRANS_CNT-1))//notransfermatch,resetstate { state_machine=STATE1; } } if(state_machine==STATE5) printf("Passwordcorrect,statetransfermachinepass!\n"); }}return0;}☆──────────────────────传说中的分隔符──────────────────────────────☆来源3:【转载3】有限状态机自动机状态图--一个图的数据结构!1.while+switch;2.状态机:就是指定系统的所有可能的状态及状态间跳转的条件,然后设一个初始状态输入给这台机器,机器就会自动运转,或最后处于终止状态,或在某一个状态不断循环。游戏中状态切换是很频繁的。可能以前要切换状态就是if~else,或者设标志,但这些都不太结构化,如果把它严格的设为一种标准的状态机,会清楚的多。比如控制一扇门的运动,初始时门是关的,当有力作用在门上时,门开始慢慢打开,力的作用完后,门渐渐停止不动,当有反向的力时,门又渐渐关上,知道回到初始关的状态。这个你会怎么来编程实现呢。似乎很麻烦,的确,没有状态机的思想时会很烦,设很多标志,一堆if条件。用状态机的话,不只是代码更清晰,关键是更符合逻辑和自然规律,不同状态不同处理,满足条件则跳转到相关状态。伪码如下:enum { CLOSED,//关上状态 CLOSING,//正在关状态 OPENED,//打开状态 OPENING,//正在开的状态 }doorState=CLOSED;//初始为关 Update() { switch(doorState) caseCLOSED: if(有人推门) doorState=OPENING;//跳转到正在开状态 break; caseOPENING: door.Rotation+=DeltaAngle;//门的旋转量递增 if(门的速度为零)//力的作用已去 doorState=OPENED;//跳转到开状态 break; caseOPENED: if(有人关门) doorState=CLOSING; break; caseCLOSING: door.Rotation-=DeltaAngle;//门的旋转量递减 if(门的旋转角度减为零) doorState=CLOSED;//门已关上 break; } //而绘制代码几乎不用怎么变,门就是会严格按照状态机的指示去运动,该停就会停 Render() { RotateView(door.Rotation); DrawDoor(door.Position); } enum{ CLOSED,//关上状态 CLOSING,//正在关状态 OPENED,//打开状态 OPENING,//正在开的状态}doorState=CLOSED;//初始为关Update(){ switch(doorState) caseCLOSED: if(有人推门) doorState=OPENING;//跳转到正在开状态 break; caseOPENING: door.Rotation+=DeltaAngle;//门的旋转量递增 if(门的速度为零)//力的作用已去 doorState=OPENED;//跳转到开状态 break; caseOPENED: if(有人关门) doorState=CLOSING; break; caseCLOSING: door.Rotation-=DeltaAngle;//门的旋转量递减 if(门的旋转角度减为零) doorState=CLOSED;//门已关上 break;}//而绘制代码几乎不用怎么变,门就是会严格按照状态机的指示去运动,该停就会停Render(){ RotateView(door.Rotation); DrawDoor(door.Position);}这是一个简单但很典型的例子,状态机的应用太多了。就说一个基本游戏的运转:(用到了一个状态然后还有子状态)UpdateGame() BEGIN; switch(gameState) case等待选择菜单://它有三个子状态。 if(选择菜单项==开始) { 游戏初始; gameState=开始游戏 } if(选择菜单项==选项) gameState=设置 if(选择菜单项==退出) gameState=退出 case开始: 游戏运行; if(用户按退出键) gameState=等待选择菜单; ...其他的状态跳转处理; case退出: 释放资源; 退出; case设置: 分别处理不同的选项,跳转不同的子状态; case....//其他状态的处理 END; UpdateGame()BEGIN; switch(gameState) case等待选择菜单://它有三个子状态。 if(选择菜单项==开始) { 游戏初始; gameState=开始游戏 } if(选择菜单项==选项) gameState=设置 if(选择菜单项==退出) gameState=退出 case开始: 游戏运行; if(用户按退出键) gameState=等待选择菜单; ...其他的状态跳转处理; case退出: 释放资源; 退出; case设置: 分别处理不同的选项,跳转不同的子状态; case....//其他状态的处理 END; 某一个状态可以包含更多的子状态,这样最好是同一层次的状态设为一个枚举,并分到另一个switch处理如enumSTATES{state1,state2,state3};state2又包含若干状态则再定义enumSUB_STATE2{sub_state2_1,sub_state2_2,sub_state2_3,};想很多基本的渲染效果,如淡入淡出,闪烁等等,用状态的思想会事半功倍,思路也更清晰。其实像Opengl,Direct3D这样的渲染引擎本身就是状态机,当你设置渲染的状态,这台机器就保持这个状态进行渲染工作,如保持光照位置,保持片元颜色,直到你再次改变它的状态。状态机的应用实在太广,相关理论也很多,最近上课学的随机过程里也讲到一些,数字电路里的时序逻辑器件也是用状态机来描述。这些不必多说了。总之,用状态机的角度去看待问题,往往能把比较复杂的系统分解为能单独处理的众多子状态,处理也会得心应手。希望大家多用它,很好的东西。二、推荐这个:[程序员杂志2004.8月刊_state模式和composite模式实现的状态机引擎]个人感觉状态机的几个不同实现阶段:1、switch/case最原始的实现方式,是很多的c程序员习惯采用的方式。2、查找表[状态、事件、动作],稍微做了一点改进。有点类似MFC的雏形。3、在以上基础上做的一些改进或者变体。[比如用一个栈结构,激活的状态位于栈顶,自动的映射事件和动作的对应,再或者通过一些巧妙的宏等手段进行包装。但是线性结构在实际中使用比较受限、过于技巧性的宏比较难于理解...]4、面向对象的设计下、灵活运用模式。如上面给出的链接。重用性和灵活性方面都有不错的表现。沿袭类似的设计思路、根据实际开发内容进行改造后利用。【评】:伪代码部分,可以帮助很好的理解【转载1】文章中叙述的FSM的实现方法1;查找表[状态、事件、动作],稍微做了一点改进。有点类似MFC的雏形类似于【转载1】文章中叙述的FSM的实现方法2(状态表)☆──────────────────────传说中的分隔符──────────────────────────────☆【转载4】fsmimplementedinCcode(FSM状态机用C实现)用C语言实现一个状态机,很简单,和大家分享这是我做毕业设计时,用nRF24L01组建了一个简单的网络,做的一个小的状态机,网络中三个节点,开始拓扑为网状,后来为星型。#include #include #include //Finitestatemachinedeclaration //statedeclaration #defineIDLE 0//idlestateinrxmode #defineM_BROADCAST 1//broadcaststateintxmode,broadcasttobeamasterpoint #defineM_WAIT_BROADCAST_ACK 2//waitforbroadcastackstateinrxmode,waitforthepointackinaspecifictimewindow #defineM_WAIT_COMMAND 3//waitforcommandstate,waitforPCcommandviaUART #defineM_BROADCAST_CANCEL 4//broadcastcancelstate,broadcasttocancelmasterpoint #defineS_BROADCAST_ACK 5//slavemode,sendbackselfphysicaladdress #defineS_WAIT_COMMAND 6//slavemode,waitforcommandfromthemasterpoint //statetransitiontrig //usedinmastermode intisReqBeMaster=0; //IsPCrequestthepointtobemaster? intisTimeout=0; //Istimeout? intisReqCancelMaster=0; //Isrequesttocancelmaster? //usedinslavemode intisRxBroadcast=0; //Isthereapointbroadcasttobemaster? intisRxBroadcastCancel=0; //Isreceivebroadcastcancelmaster? typedefstructfsmtag { intstate;//state inttimeouttime; //timeouttimeinmilliseconds }fsm; //functionprototype intmain() { fsmf; f.state=IDLE; f.timeouttime=0; while(1) { switch(f.state) { caseIDLE: puts("IDLE\nWaitforisReqBeMaster(1/0)isRxBroadcast(1/0):"); scanf("%d%d",&isReqBeMaster,&isRxBroadcast); if(isR
//continue;
break; //做了修改在vc上可以实现
来源3:
【转载3】有限状态机自动机
状态图--一个图的数据结构!
1.while+switch;
2.状态机:
就是指定系统的所有可能的状态及状态间跳转的条件,然后设一个初始状态输入给这台机器,机器就会自动运转,或最后处于终止状态,或在某一个状态不
断循环。
游戏中状态切换是很频繁的。
可能以前要切换状态就是if~else,或者设标志,但这些都不太结构化,如果把它严格的设为一种标准的状态机,会清楚的多。
比如控制一扇门的运动,初始时门是关的,当有力作用在门上时,门开始慢慢打开,力的作用完后,门渐渐停止不动,当有反向的力时,门又渐渐关上,知道回
到初始关的状态。
这个你会怎么来编程实现呢。
似乎很麻烦,的确,没有状态机的思想时会很烦,设很多标志,一堆if条件。
用状态机的话,不只是代码更清晰,关键是更符合逻辑和自然规律,不同状态不同处理,满足条件则跳转到相关状态。
伪码如下:
enum
CLOSED,//关上状态
CLOSING,//正在关状态
OPENED,//打开状态
OPENING,//正在开的状态
}doorState=CLOSED;//初始为关
Update()
switch(doorState)
caseCLOSED:
if(有人推门)
doorState=OPENING;//跳转到正在开状态
break;
caseOPENING:
door.Rotation+=DeltaAngle;//门的旋转
量递增
if(门的速度为零)//力的作用已去
doorState=OPENED;//跳转到开状态
caseOPENED:
if(有人关门)
doorState=CLOSING;
caseCLOSING:
door.Rotation-=DeltaAngle;//门的旋转量递减
if(门的旋转角度减为零)
doorState=CLOSED;//门已关上
//而绘制代码几乎不用怎么变,门就是会严格按照状态机的指示去运动,该停就会停
Render()
RotateView(door.Rotation);
DrawDoor(door.Position);
door.Rotation+=DeltaAngle;//门的旋转量递增
这是一个简单但很典型的例子,状态机的应用太多了。
就说一个基本游戏的运转:
(用到了一个状态然后还有子状态)
UpdateGame()
BEGIN;
switch(gameState)
case等待选择菜单:
//它有三个子状态。
if(选择菜单项==开始)
游戏初始;
gameState=开始游戏
if(选择菜单项==选项)
gameState=设置
if(选择菜单项==退出)
gameState=退出
case开始:
游戏运行;
if(用户按退出键)
gameState=等待选择菜单;
...其他的状态跳转处理;
case退出:
释放资源;
退出;
case设置:
分别处理不同的选项,跳转不同的子状态;
case....//其他状态的处理
END;
某一个状态可以包含更多的子状态,这样最好是同一层次的状态设为一个枚举,并分到另一个switch处理
如enumSTATES{state1,state2,state3};state2又包含若干状态
则再定义enumSUB_STATE2{sub_state2_1,sub_state2_2,sub_state2_3,};
想很多基本的渲染效果,如淡入淡出,闪烁等等,用状态的思想会事半功倍,思路也更清晰。
其实像Opengl,Direct3D这样的渲染引擎本身就是状态机,当你设置渲染的状态,这台机器就保持这个状态进行渲染工作,如保持光照位置,保持片元颜色,直到
你再次改变它的状态。
状态机的应用实在太广,相关理论也很多,最近上课学的随机过程里也讲到一些,数字电路里的时序逻辑器件也是用状态机来描述。
这些不必多说了。
总之,用状态机的角度去看待问题,往往能把比较复杂的系统分解为能单独处理的众多子状态,处理也会得心应手。
希望大家多用它,很好的东西。
二、
推荐这个:
[程序员杂志2004.8月刊_state模式和composite模式实现的状态机引擎]
个人感觉状态机的几个不同实现阶段:
1、switch/case最原始的实现方式,是很多的c程序员习惯采用的方式。
2、查找表[状态、事件、动作],稍微做了一点改进。
有点类似MFC的雏形。
3、在以上基础上做的一些改进或者变体。
[比如用一个栈结构,激活的状态位于栈顶,自动的映射事件和动作的对应,再或者通过一些巧妙的宏等手段进行包装。
但是线性结构在实际中使用比较受限、过于技
巧性的宏比较难于理解...]
4、面向对象的设计下、灵活运用模式。
如上面给出的链接。
重用性和灵活性方面都有不错的表现。
沿袭类似的设计思路、根据实际开发内容进行改造后利用。
伪代码部分,可以帮助很好的理解【转载1】文章中叙述的FSM的实现方法1;查找表[状态、事件、动作],稍微做了一点改进。
有点类似MFC的雏形类似于【转
载1】文章中叙述的FSM的实现方法2(状态表)
【转载4】fsmimplementedinCcode(FSM状态机用C实现)
用C语言实现一个状态机,很简单,和大家分享
这是我做毕业设计时,用nRF24L01组建了一个简单的网络,做的一个小的状态机,网络中三个节点,开始拓扑为网状,后来为星型。
//Finitestatemachinedeclaration
//statedeclaration
#defineIDLE 0//idlestateinrxmode
#defineM_BROADCAST 1//broadcaststateintxmode,broadcasttobeamasterpoint
#defineM_WAIT_BROADCAST_ACK 2//waitforbroadcastackstateinrxmode,waitforthepointackinaspecifictimewindow
#defineM_WAIT_COMMAND 3//waitforcommandstate,waitforPCcommandviaUART
#defineM_BROADCAST_CANCEL 4//broadcastcancelstate,broadcasttocancelmasterpoint
#defineS_BROADCAST_ACK 5//slavemode,sendbackselfphysicaladdress
#defineS_WAIT_COMMAND 6//slavemode,waitforcommandfromthemasterpoint
//statetransitiontrig
//usedinmastermode
intisReqBeMaster=0; //IsPCrequestthepointtobemaster?
intisTimeout=0; //Istimeout?
intisReqCancelMaster=0; //Isrequesttocancelmaster?
//usedinslavemode
intisRxBroadcast=0; //Isthereapointbroadcasttobemaster?
intisRxBroadcastCancel=0; //Isreceivebroadcastcancelmaster?
typedefstructfsmtag
intstate;//state
inttimeouttime; //timeouttimeinmilliseconds
}fsm;
//functionprototype
fsmf;
f.state=IDLE;
f.timeouttime=0;
while
(1)
switch(f.state)
caseIDLE:
puts("IDLE\nWaitforisReqBeMaster(1/0)isRxBroadcast(1/0):
");
scanf("%d%d",&isReqBeMaster,&isRxBroadcast);
if(isR
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1