【转载2】有限状态机的c实现2007-05-1115:12網絡上可以搜索到很多有限狀態機的代碼和理論分析,這兒僅僅是做一個簡單的例子,僅供入門參考。这儿以四位密码校验作为状态机的例子,连续输入2479就可以通过密码测试。一个非常简单的例子,在实际的状态机实例中,状态转移表要更復雜一些,不過方式非常類似。在狀態查詢的地方可以做優化,同時對于輸入量也可以做有效性優化。具體代碼如下:viewplaincopytoclipboardprint?c.htypedefenum{STATE1=1,STATE2,STATE3,STATE4,STATE5,//passwordpass//...ADDhere}STATE;typedefenum{INPUT1='2',INPUT2='4',INPUT3='7',INPUT4='9',}INPUT;typedefstruct{STATEcur_state;INPUTinput;STATEnext_state;}STATE_TRANS;c.htypedefenum{STATE1=1,STATE2,STATE3,STATE4,STATE5,//passwordpass//...ADDhere}STATE;typedefenum{INPUT1='2',INPUT2='4',INPUT3='7',INPUT4='9',}INPUT;typedefstruct{STATEcur_state;INPUTinput;STATEnext_state;}STATE_TRANS;c.c#includestdio.h#includec.hSTATE_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;iSTATE_TRANS_CNT;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#includestdio.h#includec.hSTATE_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;iSTATE_TRANS_CNT;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;}