




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、您还未登录!|登录|注册|帮助CSDN首页资讯论坛博客下载搜索更多CTO俱乐部学生大本营培训充电移动开发软件研发云计算程序员TUPguocai_yao的专栏条新通知登录注册欢迎退出我的博客配置写文章文章管理博客首页全站 当前博客 空间博客好友相册留言用户操作留言 发消息 加为好友 姚国才ID:guocai_yao共19660次访问,排名9473,好友29人,关注者35人。态度决定一切姚国才的文章原创 47 篇翻译 0 篇转载 13 篇评论 25 篇订阅我的博客编辑guocai_yao的公告 编辑文章分类APUE(Advanced Programming In The Unix Environm
2、entCC+Programming TipsskillsThe C Programming LanguageUnix环境高级编程读书笔记VC及其IDE单片机数据结构琐碎他山之玉小想法硬件电路的那些事儿编辑EmbeddedSystemAquarius (其中还有英文网站编辑高手&大师ammana_babiRichard StallmanRoland McGrathsteedhorsetaodm侯捷周立功徐艺波个人网站艺术编程陈莉君编辑好书推荐C+学习推荐书目c语言的提高编辑好友袁东存档2010年05月(82010年04月(22010年01月(52009年08月(12009年06月(120
3、09年05月(42009年04月(52009年03月(82009年02月(12009年01月(12008年05月(212008年04月(3公告: CSDN 产品事业部开设官方博客了!来关注我们的一举一动吧!意见反馈官方博客 C语言实现有限状态机 收藏 以下是转载内容:传说中的分隔符 来源1:【转载1】有限状态机的实现 < type="text/javascript"> 有限状态机(Finite State Machine或者Finite State Automata是软件领域中一种重要的工具,很多东西的模型实际上就是有限状态机。最近看了一些游戏编程AI的材料,感
4、觉游戏中的AI,第一要说的就是有限状态机来实现精灵的AI,然后才是A*寻路,其他学术界讨论比较多的神经网络、模糊控制等问题还不是很热。FSM的实现方式:1) switch/case或者if/else这无意是最直观的方式,使用一堆条件判断,会编程的人都可以做到,对简单小巧的状态机来说最合适,但是毫无疑问,这样的方式比较原始,对庞大的状态机难以维护。2) 状态表维护一个二维状态表,横坐标表示当前状态,纵坐标表示输入,表中一个元素存储下一个状态和对应的操作。这一招易于维护,但是运行时间和存储空间的代价较大。3) 使用State Pattern使用State Pattern使得代码的维护比switch
5、/case方式稍好,性能上也不会有很多的影响,但是也不是100完美。不过Robert C. Martin做了两个自动产生FSM代码的工具,for java和for C+各一个,在 Pattern的代码,这样developer的工作只需要维护状态机的文本描述,每必要冒引入bug的风险去维护code。4) 使用宏定义描述状态机一般来说,C+编程中应该避免使用#define,但是这主要是因为如果用宏来定义函数的话,很容易产生这样那样的问题,但是巧妙的使用,还是能够产生奇妙的效果。MFC就是使用宏定义来实现大的架构的。在实现FSM的时候,可以把一些繁琐无比的if/else还有花括号的组合放在宏中,这样
6、,在代码中可以3)中状态机描述文本一样写,通过编译器的预编译处理产生1)一样的效果,我见过产生C代码的宏,如果要产生C+代码,己软MFC可以,那么理论上也是可行的。 【评】:状态表的实现方法,C专家编程第8章有具体说明,转载【6】传说中的分隔符 来源2:【转载2】有限状态机的c实现2007-05-11 15:12網絡上可以搜索到很多有限狀態機的代碼和理論分析,這兒僅僅是做一個簡單的例子,僅供入門參考。这儿以四位密码校验作为状态机的例子,连续输入2479就可以通过密码测试。一个非常简单的例子,在实际的状态机实例中,状态转移表要更復雜一些,不過方式非常類似。在狀態查詢的地方可以做優化,同時對于輸入
7、量也可以做有效性優化。具體代碼如下:view plaincopy to clipboardprint?c.h typedef enum STATE1 = 1, STATE2, STATE3, STATE4, STATE5,/password pass /.ADD here STATE; typedef enum INPUT1 = '2', INPUT2 = '4', INPUT3 = '7', INPUT4 = '9', INPUT; typedef struct STATE cur_state; INPUT input; STA
8、TE next_state; STATE_TRANS; c.htypedef enumSTATE1 = 1,STATE2,STATE3,STATE4,STATE5,/password pass/.ADD hereSTATE;typedef enumINPUT1 = '2',INPUT2 = '4',INPUT3 = '7',INPUT4 = '9',INPUT;typedef structSTATE cur_state;INPUT input;STATE next_state;STATE_TRANS;c.c #include #i
9、nclude "c.h" STATE_TRANS state_trans_arry = STATE1,INPUT1,STATE2, STATE2,INPUT2,STATE3, STATE3,INPUT3,STATE4, STATE4,INPUT4,STATE5, ; #define STATE_TRANS_CNT (sizeof(state_trans_arry/sizeof(state_trans_arry0 int main( int i; char ch; STATE state_machine = STATE1; while(ch != 'e' ch
10、 = getchar(; if(ch >= '0' && (ch <= '9'/for digit password input only for(i = 0;i < STATE_TRANS_CNT;i+ if(ch = state_trans_arryi.input && (state_machine = state_trans_arryi.cur_state state_machine = state_trans_arryi.next_state; continue; else if(i = (STATE_T
11、RANS_CNT - 1/no transfer match,reset state state_machine = STATE1; if(state_machine = STATE5 printf("Password correct,state transfer machine pass!n" return 0; c.c#include #include "c.h"STATE_TRANS state_trans_arry = STATE1,INPUT1,STATE2,STATE2,INPUT2,STATE3,STATE3,INPUT3,STATE4,S
12、TATE4,INPUT4,STATE5,;#define STATE_TRANS_CNT (sizeof(state_trans_arry/sizeof(state_trans_arry0int main( int i;char ch;STATE state_machine = STATE1;while(ch != 'e'ch = getchar(;if(ch >= '0' && (ch <= '9'/for digit password input onlyfor(i = 0;i < STATE_TRANS_C
13、NT;i+if(ch = state_trans_arryi.input && (state_machine = state_trans_arryi.cur_statestate_machine = state_trans_arryi.next_state;continue;else if(i = (STATE_TRANS_CNT - 1/no transfer match,reset statestate_machine = STATE1;if(state_machine = STATE5printf("Password correct,state transfer
14、 machine pass!n"return 0;【评】:在VC6下运行该程序并没有达到目的,即连续输入字符2479也没有任何输出信息,个人根据转载第一遍文章的FSM的实现的第一种方法,见【原创之源程序】传说中的分隔符 来源3:【转载3】有限状态机自动机状态图一个图的数据结构!1.while + switch;2.状态机:就是指定系统的所有可能的状态及状态间跳转的条件,然后设一个初始状态输入给这台机器,机器就会自动运转,或最后处于终止状态,或在某一个状态不断循环。游戏中状态切换是很频繁的。 可能以前要切换状态就是ifelse,或者设标志,但这些都不太结构化, 如果把它严格的设为一种标
15、准的状态机,会清楚的多。比如控制一扇门的运动, 初始时门是关的, 当有力作用在门上时, 门开始慢慢打开,力的作用完后,门渐渐停止不动, 当有反向的力时,门又渐渐关上, 知道回到初始关的状态。 这个你会怎么来编程实现呢。 似乎很麻烦, 的确,没有状态机的思想时会很烦,设很多标志,一堆if条件。用状态机的话,不只是代码更清晰, 关键是更符合逻辑和自然规律, 不同状态不同处理, 满足条件则跳转到相关状态。伪码如下: enum CLOSED, / 关上状态 CLOSING, / 正在关状态 OPENED, / 打开状态 OPENING, / 正在开的状态 doorState = CLOSED; / 初
16、始为关 Update( switch(doorState case CLOSED: if (有人推门 doorState = OPENING; / 跳转到正在开状态 break; case OPENING: door.Rotation += DeltaAngle; / 门的旋转量递增 if (门的速度为零 / / 力的作用已去 doorState = OPENED; / 跳转到开状态 break; case OPENED: if (有人关门 doorState = CLOSING; break; case CLOSING: door.Rotation -= DeltaAngle; / 门的旋转
17、量递减 if (门的旋转角度减为零 doorState = CLOSED; / 门已关上 break; / 而绘制代码几乎不用怎么变, 门就是会严格按照状态机的指示去运动, 该停就会停 Render( RotateView(door.Rotation; DrawDoor(door.Position; enumCLOSED, / 关上状态CLOSING, / 正在关状态OPENED, / 打开状态OPENING, / 正在开的状态doorState = CLOSED; / 初始为关Update(switch(doorStatecase CLOSED:if (有人推门doorState = OPE
18、NING; / 跳转到正在开状态break;case OPENING:door.Rotation += DeltaAngle; / 门的旋转量递增if (门的速度为零 / / 力的作用已去doorState = OPENED; / 跳转到开状态break;case OPENED:if (有人关门doorState = CLOSING;break;case CLOSING:door.Rotation -= DeltaAngle; / 门的旋转量递减if (门的旋转角度减为零doorState = CLOSED; / 门已关上break; / 而绘制代码几乎不用怎么变, 门就是会严格按照状态机的指
19、示去运动, 该停就会停Render(RotateView(door.Rotation;DrawDoor(door.Position;这是一个简单但很典型的例子, 状态机的应用太多了。就说一个基本游戏的运转: (用到了一个状态然后还有子状态)UpdateGame( BEGIN; switch(gameState case 等待选择菜单: /它有三个子状态。 if (选择菜单项 开始 游戏初始; gameState = 开始游戏 if (选择菜单项 选项 gameState = 设置 if (选择菜单项 退出 gameState = 退出 case 开始: 游戏运行; if (用户按退出键 gam
20、eState = 等待选择菜单 ; .其他的状态跳转处理; case 退出: 释放资源; 退出; case 设置: 分别处理不同的选项, 跳转不同的子状态; case . / 其他状态的处理 END; UpdateGame(BEGIN;switch(gameStatecase 等待选择菜单: /它有三个子状态。if (选择菜单项 开始游戏初始;gameState = 开始游戏if (选择菜单项 选项gameState = 设置if (选择菜单项 退出gameState = 退出case 开始:游戏运行;if (用户按退出键gameState = 等待选择菜单 ;.其他的状态跳转处理;case
21、退出:释放资源;退出;case 设置:分别处理不同的选项, 跳转不同的子状态;case . / 其他状态的处理END;某一个状态可以包含更多的子状态, 这样最好是同一层次的状态设为一个枚举, 并分到另一个switch处理如 enum STATESstate1, state2, state3; state2又包含若干状态则再定义enum SUB_STATE2sub_state2_1, sub_state2_2, sub_state2_3,;想很多基本的渲染效果, 如淡入淡出, 闪烁等等, 用状态的思想会事半功倍, 思路也更清晰。其实像Opengl, Direct3D这样的渲染引擎本身就是状态机,
22、 当你设置渲染的状态, 这台机器就保持这个状态进行渲染工作,如保持光照位置,保持片元颜色, 直到你再次改变它的状态。状态机的应用实在太广, 相关理论也很多, 最近上课学的随机过程里也讲到一些, 数字电路里的时序逻辑器件也是用状态机来描述。 这些不必多说了。总之, 用状态机的角度去看待问题, 往往能把比较复杂的系统分解为能单独处理的众多子状态, 处理也会得心应手。希望大家多用它, 很好的东西。二、推荐这个:程序员杂志2004.8月刊_state模式和composite模式实现的状态机引擎个人感觉状态机的几个不同实现阶段:1、switch/case 最原始的实现方式,是很多的c程序员习惯采用的方式
23、。2、查找表状态、事件、动作,稍微做了一点改进。有点类似MFC的雏形。3、在以上基础上做的一些改进或者变体。比如用一个栈结构,激活的状态位于栈顶,自动的映射事件和动作的对应,再或者通过一些巧妙的宏等手段进行包装。但是线性结构在实际中使用比较受限、过于技巧性的宏比较难于理解.4、面向对象的设计下、灵活运用模式。如上面给出的链接。重用性和灵活性方面都有不错的表现。沿袭类似的设计思路、根据实际开发内容进行改造后利用。【评】:伪代码部分,可以帮助很好的理解【转载1】文章中叙述的FSM的实现方法1;查找表状态、事件、动作,稍微做了一点改进。有点类似MFC的雏形类似于【转载1】文章中叙述的FSM的实现方法
24、2(状态表)传说中的分隔符 来源4:【转载4】fsm implemented in C code(FSM状态机用C实现用C语言实现一个状态机,很简单,和大家分享这是我做毕业设计时,用nRF24L01组建了一个简单的网络,做的一个小的状态机,网络中三个节点,开始拓扑为网状,后来为星型。#include #include #include /Finite state machine declaration /state declaration #define IDLE 0 /idle state in rx mode #define M_BROADCAST 1 /broadcast state i
25、n tx mode,broadcast to be a master point #define M_WAIT_BROADCAST_ACK 2 /wait for broadcast ack state in rx mode,wait for the point ack in a specific time window #define M_WAIT_COMMAND 3 /wait for command state,wait for PC command via UART #define M_BROADCAST_CANCEL 4 /broadcast cancel state,broadca
26、st to cancel master point #define S_BROADCAST_ACK 5 /slave mode,send back self physical address #define S_WAIT_COMMAND 6 /slave mode, wait for command from the master point /state transition trig /used in master mode int isReqBeMaster = 0;/Is PC request the point to be master? int isTimeout = 0;/Is
27、time out? int isReqCancelMaster = 0;/Is request to cancel master? /used in slave mode int isRxBroadcast = 0;/Is there a point broadcast to be master? int isRxBroadcastCancel = 0;/Is receive broadcast cancel master? typedef struct fsmtag int state; /state int timeouttime; /time out time in millisecon
28、ds fsm; /function prototype int main( fsm f; f.state = IDLE; f.timeouttime = 0; while(1 switch(f.state case IDLE: puts("IDLEnWait for isReqBeMaster(1/0 isRxBroadcast(1/0:" scanf("%d %d",&isReqBeMaster,&isRxBroadcast; if(isReqBeMaster f.state = M_BROADCAST; break; else if(
29、isRxBroadcast f.state = S_BROADCAST_ACK; break; else break; case M_BROADCAST: puts("M_BROADCASTnBroadcasting.n" f.state = M_WAIT_BROADCAST_ACK; case M_WAIT_BROADCAST_ACK: puts("M_WAIT_BROADCAST_ACKnWaiting for isTimeout(1/0:" scanf("%d",&isTimeout; if(isTimeout f.st
30、ate = M_WAIT_COMMAND; break; else break; case M_WAIT_COMMAND: puts("M_WAIT_COMMANDnWaiting for isReqCancelMaster(1/0:" scanf("%d",&isReqCancelMaster; if(isReqCancelMaster f.state = IDLE; break; else break; /Slave mode routine case S_BROADCAST_ACK: puts("S_BROADCAST_ACKnA
31、cking.n" f.state = S_WAIT_COMMAND; break; case S_WAIT_COMMAND: puts("S_WAIT_COMMANDnWaiting for isRxBroadcastCancel(1/0:" scanf("%d",&isRxBroadcastCancel; if(isRxBroadcastCancel f.state = IDLE; break; else break; default: puts("default" printf("%dn",r
32、and(; f.state = IDLE; return 0; #include #include #include /Finite state machine declaration/state declaration#define IDLE 0 /idle state in rx mode#define M_BROADCAST 1 /broadcast state in tx mode,broadcast to be a master point#define M_WAIT_BROADCAST_ACK 2 /wait for broadcast ack state in rx mode,w
33、ait for the point ack in a specific time window#define M_WAIT_COMMAND 3 /wait for command state,wait for PC command via UART#define M_BROADCAST_CANCEL 4 /broadcast cancel state,broadcast to cancel master point#define S_BROADCAST_ACK 5 /slave mode,send back self physical address#define S_WAIT_COMMAND
34、 6 /slave mode, wait for command from the master point/state transition trig/used in master modeint isReqBeMaster = 0;/Is PC request the point to be master?int isTimeout = 0;/Is time out?int isReqCancelMaster = 0;/Is request to cancel master?/used in slave modeint isRxBroadcast = 0;/Is there a point
35、 broadcast to be master?int isRxBroadcastCancel = 0;/Is receive broadcast cancel master?typedef struct fsmtagint state; /stateint timeouttime; /time out time in millisecondsfsm;/function prototypeint main(fsm f;f.state = IDLE;f.timeouttime = 0;while(1switch(f.statecase IDLE:puts("IDLEnWait for
36、isReqBeMaster(1/0 isRxBroadcast(1/0:"scanf("%d %d",&isReqBeMaster,&isRxBroadcast;if(isReqBeMasterf.state = M_BROADCAST;break;else if(isRxBroadcastf.state = S_BROADCAST_ACK;break;elsebreak;case M_BROADCAST:puts("M_BROADCASTnBroadcasting.n"f.state = M_WAIT_BROADCAST_AC
37、K;case M_WAIT_BROADCAST_ACK:puts("M_WAIT_BROADCAST_ACKnWaiting for isTimeout(1/0:"scanf("%d",&isTimeout;if(isTimeoutf.state = M_WAIT_COMMAND;break;elsebreak;case M_WAIT_COMMAND:puts("M_WAIT_COMMANDnWaiting for isReqCancelMaster(1/0:"scanf("%d",&isReqCa
38、ncelMaster;if(isReqCancelMasterf.state = IDLE;break;elsebreak;/Slave mode routinecase S_BROADCAST_ACK:puts("S_BROADCAST_ACKnAcking.n"f.state = S_WAIT_COMMAND;break;case S_WAIT_COMMAND:puts("S_WAIT_COMMANDnWaiting for isRxBroadcastCancel(1/0:"scanf("%d",&isRxBroadcas
39、tCancel;if(isRxBroadcastCancelf.state = IDLE;break;elsebreak;default:puts("default"printf("%dn",rand(;f.state = IDLE;return 0;【评】:很实用的一个状态机程序传说中的分隔符 来源5:/user1/349/archives/2007/44609.html【转载5】状态机的两种写法2004/12/26 asdjfyy20041226-1v1有限状态机FSM思想广泛应用于硬件控制电路设计,也是软件
40、上常用的一种处理方法(软件上称为FMM-有限消息机。它把复杂的控制逻辑分解成有限个稳定状态,在每个状态上判断事件,变连续处理为离散数字处理,符合计算机的工作特点。同时,因为有限状态机具有有限个状态,所以可以在实际的工程上实现。但这并不意味着其只能进行有限次的处理,相反,有限状态机是闭环系统,有限无穷,可以用有限的状态,处理无穷的事务。有限状态机的工作原理如图1所示,发生事件(event后,根据当前状态(cur_state,决定执行的动作(action,并设置下一个状态号(nxt_state。-| |->执行动作action发生事件event ->| cur_state | |-&g
41、t;设置下一状态号nxt_state-当前状态图1 有限状态机工作原理e0/a0->-| |->-e0/a0 | | S0 |-| -<- | e1/a1| | e2/a2 V- -| S2 |-<-| S1 |- e2/a2 -图2 一个有限状态机实例-当前状态 s0 s1 s2 | 事件-a0/s0 - a0/s0 | e0-a1/s1 - - | e1-a2/s2 a2/s2 - | e2-表1 图2状态机实例的二维表格表示(动作/下一状态图2为一个状态机实例的状态转移图,它的含义是:在s0状态,如果发生e0事件,那么就执行a0动作,并保持状态不变;如果发生e1事
42、件,那么就执行a1动作,并将状态转移到s1态;如果发生e2事件,那么就执行a2动作,并将状态转移到s2态;在s1状态,如果发生e2事件,那么就执行a2动作,并将状态转移到s2态;在s2状态,如果发生e0事件,那么就执行a0动作,并将状态转移到s0态;有限状态机不仅能够用状态转移图表示,还可以用二维的表格代表。一般将当前状态号写在横行上,将事件写在纵列上,如表1所示。其中“-”表示空(不执行动作,也不进行状态转移,“an/sn”表示执行动作an,同时将下一状态设置为sn。表1和图2表示的含义是完全相同的。观察表1可知,状态机可以用两种方法实现:竖着写(在状态中判断事件和横着写(在事件中判断状态。
43、这两种实现在本质上是完全等效的,但在实际操作中,效果却截然不同。=竖着写(在状态中判断事件C代码片段=cur_state = nxt_state;switch(cur_state /在当前状态中判断事件case s0: /在s0状态if(e0_event /如果发生e0事件,那么就执行a0动作,并保持状态不变;执行a0动作;/nxt_state = s0; /因为状态号是自身,所以可以删除此句,以提高运行速度。else if(e1_event /如果发生e1事件,那么就执行a1动作,并将状态转移到s1态;执行a1动作;nxt_state = s1;else if(e2_event /如果发生e
44、2事件,那么就执行a2动作,并将状态转移到s2态;执行a2动作;nxt_state = s2;break;case s1: /在s1状态if(e2_event /如果发生e2事件,那么就执行a2动作,并将状态转移到s2态;执行a2动作;nxt_state = s2;break;case s2: /在s2状态if(e0_event /如果发生e0事件,那么就执行a0动作,并将状态转移到s0态;执行a0动作;nxt_state = s0;=横着写(在事件中判断状态C代码片段=/e0事件发生时,执行的函数void e0_event_function(int * nxt_stateint cur_st
45、ate;cur_state = *nxt_state;switch(cur_statecase s0: /观察表1,在e0事件发生时,s1处为空case s2:执行a0动作;*nxt_state = s0;/e1事件发生时,执行的函数void e1_event_function(int * nxt_stateint cur_state;cur_state = *nxt_state;switch(cur_statecase s0: /观察表1,在e1事件发生时,s1和s2处为空执行a1动作;*nxt_state = s1;/e2事件发生时,执行的函数void e2_event_function(
46、int * nxt_stateint cur_state;cur_state = *nxt_state;switch(cur_statecase s0: /观察表1,在e2事件发生时,s2处为空case s1:执行a2动作;*nxt_state = s2;上面横竖两种写法的代码片段,实现的功能完全相同,但是,横着写的效果明显好于竖着写的效果。理由如下:1、竖着写隐含了优先级排序(其实各个事件是同优先级的,排在前面的事件判断将毫无疑问地优先于排在后面的事件判断。这种if/else if写法上的限制将破坏事件间原有的关系。而横着写不存在此问题。2、由于处在每个状态时的事件数目不一致,而且事件发生的
47、时间是随机的,无法预先确定,导致竖着写沦落为顺序查询方式,结构上的缺陷使得大量时间被浪费。对于横着写,在某个时间点,状态是唯一确定的,在事件里查找状态只要使用switch语句,就能一步定位到相应的状态,延迟时间可以预先准确估算。而且在事件发生时,调用事件函数,在函数里查找唯一确定的状态,并根据其执行动作和状态转移的思路清晰简洁,效率高,富有美感。总之,我个人认为,在软件里写状态机,使用横着写的方法比较妥帖。竖着写的方法也不是完全不能使用,在一些小项目里,逻辑不太复杂,功能精简,同时为了节约内存耗费,竖着写的方法也不失为一种合适的选择。在FPGA类硬件设计中,以状态为中心实现控制电路状态机(竖着
48、写似乎是唯一的选择,因为硬件不太可能靠事件驱动(横着写。不过,在FPGA里有一个全局时钟,在每次上升沿时进行状态切换,使得竖着写的效率并不低。虽然在硬件里竖着写也要使用IF/ELSIF这类查询语句(用VHDL开发,但他们映射到硬件上是组合逻辑,查询只会引起门级延迟(ns量级,而且硬件是真正并行工作的,这样竖着写在硬件里就没有负面影响。因此,在硬件设计里,使用竖着写的方式成为必然的选择。这也是为什么很多搞硬件的工程师在设计软件状态机时下意识地只使用竖着写方式的原因,盖思维定势使然也。TCP和PPP框架协议里都使用了有限状态机,这类软件状态机最好使用横着写的方式实现。以某TCP协议为例,见图3,有
49、三种类型的事件:上层下达的命令事件;下层到达的标志和数据的收包事件;超时定时器超时事件。上层命令(open,close事件-| TCP | <-超时事件timeout-RST/SYN/FIN/ACK/DATA等收包事件图3 三大类TCP状态机事件由图3可知,此TCP协议栈采用横着写方式实现,有3种事件处理函数,上层命令处理函数(如tcp_close;超时事件处理函数(tmr_slow;下层收包事件处理函数(tcp_process。值得一提的是,在收包事件函数里,在各个状态里判断RST/SYN/FIN/ACK/DATA等标志(这些标志类似于事件,看起来象竖着写方式,其实,如果把包头和数据看
50、成一个整体,那么,RST/SYN/FIN/ACK/DATA等标志就不必被看成独立的事件,而是属于同一个收包事件里的细节,这样,就不会认为在状态里查找事件,而是总体上看,是在收包事件里查找状态(横着写。在PPP里更是到处都能见到横着写的现象,有时间的话再细说。我个人感觉在实现PPP框架协议前必须了解横竖两种写法,而且只有使用横着写的方式才能比较完美地实现PPP。【评】:看不大懂,先留着,有备无患传说中的分隔符 来源6:【转载6】用C语言实现有限状态机-读C专家编程有限状态机(finite state machine是一个数学概念,如果把它运用于程序中,可以发挥很大的作用。它是一种协议,用于有限数
51、量的子程序("状态"的发展变化。每个子程序进行一些处理并选择下一种状态(通常取决于下一段输入。有限状态机(FSM可以用作程序的控制结构。FSM对于那些基于输入的在几个不同的可选动作中进行循环的程序尤其合适。投币售货机就是FSM的一个好例子。另外一个你可以想到的复杂的例子就是你正在用的东西,想到了吗?没错,就是操作系统。在投币售货机的例子中,输入是硬币,输出是待售商品,售货机有"接受硬币","选择商品","发送商品"和"找零钱"等几种状态。它的基本思路是用一张表保存所有可能的状态,并列出进入每个状态时可能执行的所有动作,其中最后一个动作就是计算(通常在当前状态和下一次输入字符的基础上,另外再经过一次表查询下一个应该进入的状态。你从一个"初始状态"开始。在这一过程中,翻译表可能告诉你进入了一个错误状态,直到到达结束状态。在C语言中,有好几种方法可以用来表达FSM,但它们绝大多数都是基于函数指针数组。一个函数指针数组可以像下面这样声明:void (*stateMAX_STA
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论