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