特定のコードはわかりませんが、次のような理由があります。
typedef enum {
STATE1, STATE2, STATE3
} myState_e;
void myFsm(void)
{
myState_e State = STATE1;
while(1)
{
switch(State)
{
case STATE1:
State = STATE2;
break;
case STATE2:
State = STATE3;
break;
case STATE3:
State = STATE1;
break;
}
}
}
あなたのために働かないだろうか?を使用せずgoto
、比較的簡単にフォローできます。
編集:これらのState =
フラグメントはすべてDRYに違反しているため、代わりに次のようなことを行う可能性があります。
typedef int (*myStateFn_t)(int OldState);
int myStateFn_Reset(int OldState, void *ObjP);
int myStateFn_Start(int OldState, void *ObjP);
int myStateFn_Process(int OldState, void *ObjP);
myStateFn_t myStateFns[] = {
#define MY_STATE_RESET 0
myStateFn_Reset,
#define MY_STATE_START 1
myStateFn_Start,
#define MY_STATE_PROCESS 2
myStateFn_Process
}
int myStateFn_Reset(int OldState, void *ObjP)
{
return shouldStart(ObjP) ? MY_STATE_START : MY_STATE_RESET;
}
int myStateFn_Start(int OldState, void *ObjP)
{
resetState(ObjP);
return MY_STATE_PROCESS;
}
int myStateFn_Process(int OldState, void *ObjP)
{
return (process(ObjP) == DONE) ? MY_STATE_RESET : MY_STATE_PROCESS;
}
int stateValid(int StateFnSize, int State)
{
return (State >= 0 && State < StateFnSize);
}
int stateFnRunOne(myStateFn_t StateFns, int StateFnSize, int State, void *ObjP)
{
return StateFns[OldState])(State, ObjP);
}
void stateFnRun(myStateFn_t StateFns, int StateFnSize, int CurState, void *ObjP)
{
int NextState;
while(stateValid(CurState))
{
NextState = stateFnRunOne(StateFns, StateFnSize, CurState, ObjP);
if(! stateValid(NextState))
LOG_THIS(CurState, NextState);
CurState = NextState;
}
}
もちろん、これは最初の試みよりもはるかに長いです(DRYの面白いこと)。State =
ただし、より堅牢でもあります。状態関数の1つから状態を返さないと、以前のコードの欠落を黙って無視するのではなく、コンパイラの警告が発生します。