C编程查找表

时间:2013-08-14 13:10:28

标签: c state-machine

经过一些帮助,因为有一些代码可以工作,但试图完全理解一个小部分,它使用查找表作为状态机的一部分。我理解并一直用于我正在编写的教程的状态机http://coder-tronics.com/state-machine-tutorial-pt1 而不是在UponExit,UponEnter和ActionWhileInState中使用更多switch case语句,有人建议使用我喜欢但不完全理解的方法。

现在我不确定的部分是这些与typedef和lookup表

相关的行
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;
}

谢谢,

蚂蚁

1 个答案:

答案 0 :(得分: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};

每个持有三个不同的函数指针,每个状态一个。所以像

这样的一行
UponExit[Current_State]();
如果UponExit[Current_State]为0,则

调用指针hExit_OFF指向Current_State的函数,如果hExit_ON为1或Current_State,则hExit_PROCESS如果Current_State是2。 你也可以这样写一行:

(*UponExit[Current_State])();

看起来更复杂,但明确指出UponExit[Current_State]是一个函数指针,它被“取消引用”到它所指向的函数的调用。

修改

您的州有enum

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

因此,S_OFF == 0S_ON == 1S_PROCESS == 2S_MAX == 3(看here