C语言实现状态机
1.建立相应的状态表和动作查询表
2.根据状态表、事件、动作表定位相应的动作处理函数
3.执行完之后在进行状态的切换
#include <stdio.h>
//定义状态数据的枚举类型
typedef enum{
state_1 = 1,
state_2,
state_3,
state_4,
}State;
//定义事件的枚举类型
typedef enum{
event_1 = 1,
event_2,
event_3,
event_4,
event_5,
}EventID;
//定义状态表的数据类型
typedef struct
{
int event;//事件
int CurState;//当前状态
void (*eventActFun) ();//函数指针
int NextSate;//下一个状态
}StateTable;
//定义处理函数
void f1()
{
printf("this is 1\n");
}
void f2()
{
printf("this is 2\n");
}
void f3()
{
printf("this is 3\n");
}
void f4()
{
printf("this is 4\n");
}
//建立状态表
StateTable fTable[] =
{
//到来的事件,当前状态,将要执行的函数,下一个状态
{event_1,state_1,f1,event_2},
{event_2,state_2,f2,event_3},
{event_3,state_3,f3,event_4},
{event_4,state_4,f4,event_1},
};
//状态机类型,状态机接口函数
typedef struct
{
int curState;//当前状态
StateTable *stateTable;//状态表
int size;//表的项数
}fsmType;
//给状态机注册,给予状态表
void fsmRegist(fsmType* pFsm,StateTable* pTable)
{
pFsm->stateTable = pTable;
}
//状态转移
void fsmStateTransfer(fsmType* pFsm,int state)
{
pFsm->curState = state;
}
//事件处理
void fsmEventHandle(fsmType* pFsm,int event)
{
StateTable* pActTable = pFsm->stateTable;
void (*eventActFun)() = NULL;//函数指针初始化为空
int NextState;
int CurState = pFsm->curState;
int maxNum = pFsm->size;
int flag = 0;//标志是否满足条件
//获得当前动作函数
for(int i = 0;i<maxNum;i++)
{
//当前仅当当前状态下,来个指定的事件执行
if(event == pActTable[i].event && CurState == pActTable[i].CurState)
{
flag = 1;
eventActFun = pActTable[i].eventActFun;
NextState = pActTable[i].NextSate;
break;
}
}
if(flag)//如果满足条件了
{
//动作执行
if(eventActFun)
{
eventActFun();
}
//跳转到下一个状态
fsmStateTransfer(pFsm,NextState);
}
else
{
printf("there is no match\n");
}
}
int main()
{
fsmType pType;
fsmRegist(&pType,fTable);
pType.curState = state_1;
pType.size = sizeof(fTable)/sizeof(StateTable);
//printf("init state:%d\n\n",pType.curState);
fsmEventHandle(&pType,event_1);
printf("state:%d\n\n",pType.curState);
fsmEventHandle(&pType,event_2);
printf("state:%d\n\n",pType.curState);
fsmEventHandle(&pType,event_3);
printf("state:%d\n\n",pType.curState);
fsmEventHandle(&pType,event_4);
printf("state:%d\n\n",pType.curState);
fsmEventHandle(&pType,event_2);
printf("state:%d\n\n",pType.curState);
return 0;
}