Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C程序设计查找表_C_State Machine - Fatal编程技术网

C程序设计查找表

C程序设计查找表,c,state-machine,C,State Machine,在获得一些帮助后,我们将编写一些代码,这些代码可以正常工作,但我们将尝试完全理解一个小部分,该部分使用查找表作为状态机的一部分。我理解的状态机,并且在这里找到了我正在编写的教程中一直在使用它 在UponExit、uponeter和ActionWhileInState中没有使用更多的switch-case语句,而是有人建议使用我喜欢但不完全理解的方法 现在我不确定的部分是这些行与typedef和lookup表有关 typedef void (* const voidFunc)(void); vo

在获得一些帮助后,我们将编写一些代码,这些代码可以正常工作,但我们将尝试完全理解一个小部分,该部分使用查找表作为状态机的一部分。我理解的状态机,并且在这里找到了我正在编写的教程中一直在使用它 在UponExit、uponeter和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和lookup表,对它们有了基本的了解,但我希望有人能简要介绍一下这种情况下的工作原理

为了完整起见,下面是与此相关的代码的完整部分

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;
}
谢谢

蚂蚁

是函数指针的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]
指向的函数,如果
Current_State
为0,
hExit_ON
如果
Current_State
为1或
hExit_进程
如果
Current_State
为2。 你也可以这样写:

(*UponExit[Current_State])();
什么看起来更复杂,但清楚地表明,
UponExit[Current_State]
是一个函数指针,它被“取消引用”到它所指向的函数的调用

编辑:

您的州有一个
enum

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

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

您好Ingo,感谢您的及时回复。这有助于但承认仍然有点困惑,但如果我们看一下状态机函数的开关情况,第一种情况S_OFF as=0,然后S_ON as=1,最后S_PROCESS as=2,我会说得对吗?Ingo,再次感谢您将您的回答标记为答案,但还有最后一个问题。其中voidFunc uponeter[S_MAX]={hEnter_OFF,hEnter_ON,hEnter_PPROCESS};此处是否使用S_MAX,因为这是默认的返回值(如果没有其他值)returned@Ant:不,不是。该声明仅表示
uponetry
S_MAX
元素组成,索引为0到S_MAX-1。如果您试图访问
UponEntry[S_MAX]
(或
UponEntry[i]
,对于任何
i
<0或>=S_MAX),这将是未定义的行为,很可能会导致崩溃,谢谢,所以S_MAX就像声明数组时的结束值?它是数组大小(元素数)。它只是声明数组使用了大量内存,而与任何数组元素的内容无关。
enum states { S_OFF, S_ON, S_PROCESS, S_MAX };