I was researching about state machines using C, and I ran into this code from this site.
There is some typedef
declaration that I had never seen before:
typedef eSystemState (*const afEventHandler[last_State][last_Event])(void);
and it is used here:
// Table to define valid states and event of finite state machine
static afEventHandler StateMachine =
{
[Idle_State] ={[Card_Insert_Event]= InsertCardHandler },
[Card_Inserted_State] ={[Pin_Enter_Event] = EnterPinHandler },
[Pin_Eentered_State] ={[Option_Selection_Event] = OptionSelectionHandler},
[Option_Selected_State] ={[Amount_Enter_Event] = EnterAmountHandler},
[Amount_Entered_State] ={[Amount_Dispatch_Event] = AmountDispatchHandler},
};
Can somebody please explain what this is? Here is the full code
#include <stdio.h>
//Different state of ATM machine
typedef enum
{
Idle_State,
Card_Inserted_State,
Pin_Eentered_State,
Option_Selected_State,
Amount_Entered_State,
last_State
} eSystemState;
//Different type events
typedef enum
{
Card_Insert_Event,
Pin_Enter_Event,
Option_Selection_Event,
Amount_Enter_Event,
Amount_Dispatch_Event,
last_Event
} eSystemEvent;
//typedef of 2d array
typedef eSystemState (*const afEventHandler[last_State][last_Event])(void);
//typedef of function pointer
typedef eSystemState (*pfEventHandler)(void);
//function call to dispatch the amount and return the ideal state
eSystemState AmountDispatchHandler(void)
{
return Idle_State;
}
//function call to Enter amount and return amount enetered state
eSystemState EnterAmountHandler(void)
{
return Amount_Entered_State;
}
//function call to option select and return the option selected state
eSystemState OptionSelectionHandler(void)
{
return Option_Selected_State;
}
//function call to enter the pin and return pin entered state
eSystemState EnterPinHandler(void)
{
return Pin_Eentered_State;
}
//function call to processing track data and return card inserted state
eSystemState InsertCardHandler(void)
{
return Card_Inserted_State;
}
int main(int argc, char *argv[])
{
eSystemState eNextState = Idle_State;
eSystemEvent eNewEvent;
// Table to define valid states and event of finite state machine
static afEventHandler StateMachine =
{
[Idle_State] ={[Card_Insert_Event]= InsertCardHandler },
[Card_Inserted_State] ={[Pin_Enter_Event] = EnterPinHandler },
[Pin_Eentered_State] ={[Option_Selection_Event] = OptionSelectionHandler},
[Option_Selected_State] ={[Amount_Enter_Event] = EnterAmountHandler},
[Amount_Entered_State] ={[Amount_Dispatch_Event] = AmountDispatchHandler},
};
while(1)
{
// assume api to read the next event
eSystemEvent eNewEvent = ReadEvent();
//Check NULL pointer and array boundary
if( ( eNextState < last_State) && (eNewEvent < last_Event) && StateMachine[eNextState][eNewEvent]!= NULL)
{
// function call as per the state and event and return the next state of the finite state machine
eNextState = (*StateMachine[eNextState][eNewEvent])();
}
else
{
//Invalid
}
}
return 0;
}
Let's consider the typedef
step by step.
This
declares a two dimensional array. Taking into account that the enumerators
last_State
andlastEvent
are equal to5
then the above record is equivalent toThis
declares a two-dimensional array of constant pointers (the pointers themselves are constant).
And at last this
declares a two-dimensional array of constant pointers to functions of the type
eSystemState ( void )
. That is the function has the return typeeSystemState
and the parameter listvoid
.Thus the name
afEventHandler
is a synonym for the type of a two-dimensional array of constant pointers to functions of the typeeSystemState ( void )
As for this declaration
Then an array of the type described above is declared and initialized using designated initializers.
Here is a much more simplified example of a similar typedef declaration of a one-dimensional array of function pointers using an enumeration.
The program output is