3

いくつかのコードが機能するように助けた後、ルックアップテーブルをステートマシンの一部として使用する小さなセクションを完全に理解しようとしています。私が理解し、私が書いているチュートリアルで使用しているステート マシンは、ここ にありますhttp://coder-tronics.com/state-machine-tutorial-pt1私は好きですが、完全には理解していないこの方法を使用することを提案しました。

今私が確信していない部分は、これらの行がtypedefとルックアップテーブルに関係していることです

typedef void (* const voidFunc)(void);

voidFunc UponEnter[S_MAX] =          {hEnter_OFF,   hEnter_ON,   hEnter_PROCESS};
voidFunc ActionWhileInState[S_MAX] = {hInState_OFF, hInState_ON, hInState_PROCESS};
voidFunc UponExit[S_MAX] =           {hExit_OFF,    hExit_ON,    hExit_PROCESS};

私は typedef とルックアップ テーブルを調べて、基本的な理解を持っていますが、誰かがこの場合にこれがどのように機能するかについて簡単に説明できることを望んでいましたか?

これに関連するコードの完全な部分は、完全を期すために以下に示します。

enum states { S_OFF, S_ON, S_PROCESS, S_MAX };
enum events { E_OFF, E_ON, E_START, E_MAX};
typedef void (* const voidFunc)(void);
void hEnter_OFF(void);   void hEnter_ON(void);   void hEnter_PROCESS(void);
void hInState_OFF(void); void hInState_ON(void); void hInState_PROCESS(void);
void hExit_OFF(void);    void hExit_ON(void);    void hExit_PROCESS(void);

voidFunc UponEnter[S_MAX] =          {hEnter_OFF,   hEnter_ON,   hEnter_PROCESS};
voidFunc ActionWhileInState[S_MAX] = {hInState_OFF, hInState_ON, hInState_PROCESS};
voidFunc UponExit[S_MAX] =           {hExit_OFF,    hExit_ON,    hExit_PROCESS};

enum states StateMachine(enum events event, enum states Current_State)
{
    int Next_State = Current_State;

    switch ( Current_State )
    {
            case S_OFF:
       switch (event )
       {
           // A transition to the next state will occur here
           case E_ON:
            Next_State = S_ON;
               break;
           default:     // Default case placed here to avoid Eclipse warnings as Eclipse expects
               break;   //to handle all enumerated values
       }
       break;
   case S_ON:
       switch (event )
       {
           // A transition to the next state will occur here
           case E_OFF:
            Next_State = S_OFF;
               break;
           case E_START:
            Next_State = S_PROCESS;
               break;
           default:     // Default case placed here to avoid Eclipse warnings as Eclipse expects
               break;   //to handle all enumerated values
       }
       break;
   case S_PROCESS:
       switch (event )
       {
           // A transition to the next state will occur here
       case E_OFF:
        Next_State = S_OFF;
           break;
       default:     // Default case placed here to avoid Eclipse warnings as Eclipse expects
           break;   //to handle all enumerated values
       }
       break;
       // The program should never arrive here
    default:
       break;
    }

    if (Next_State != Current_State)
    {
        // Function call for Upon Exit function, it can be omitted but allows extra functionality
        UponExit[Current_State]();
        // Function call for Upon Enter function, it can be omitted but allows extra functionality
        if (Next_State != S_MAX) UponEnter[Next_State]();
    }
    else // I think ActionWhileInState should only be called when NOT doing a transition!
     {
        if ( event != E_MAX) ActionWhileInState[Current_State]();
    }
    return Next_State;
}

ありがとう、

4

1 に答える 1

3
typedef void (* const voidFunc)(void);

関数ポインターの typedef です (パラメーターを期待せず、正確には何も返さない関数へのポインターの場合)。だからあなたの配列

voidFunc UponEnter[S_MAX] =          {hEnter_OFF,   hEnter_ON,   hEnter_PROCESS};
voidFunc ActionWhileInState[S_MAX] = {hInState_OFF, hInState_ON, hInState_PROCESS}; 
voidFunc UponExit[S_MAX] =           {hExit_OFF,    hExit_ON,    hExit_PROCESS};

それぞれが、各状態に 1 つずつ、3 つの異なる関数ポインターを保持します。だから、次のような行

UponExit[Current_State]();

if is 0、if is 1、またはif is 2 であるポインタがUponExit[Current_State]指す関数を呼び出します。次のような行を書くこともできます。hExit_OFFCurrent_StatehExit_ONCurrent_StatehExit_PROCESSCurrent_State

(*UponExit[Current_State])();

UponExit[Current_State]より複雑に見えますが、それが指す関数への呼び出しに「逆参照」される関数ポインターであることを明確にしています。

編集:

あなたenumの州には次のものがあります。

enum states { S_OFF, S_ON, S_PROCESS, S_MAX };

したがって、S_OFF == 0S_ON == 1S_PROCESS == 2およびS_MAX == 3(こちらを参照)

于 2013-08-14T14:07:54.620 に答える