【问题标题】:What is this ```typedef``` declaration?这个 ```typedef``` 声明是什么?
【发布时间】:2021-04-29 10:11:49
【问题描述】:

我正在研究使用 C 的状态机,我从this site 遇到了这段代码。 有一些我以前从未见过的typedef 声明:

    typedef eSystemState (*const afEventHandler[last_State][last_Event])(void); 

在这里使用:

    // 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},
    };

有人能解释一下这是什么吗?这是完整的代码

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

【问题讨论】:

    标签: c multidimensional-array function-pointers typedef designated-initializer


    【解决方案1】:

    让我们考虑 typedef

    typedef eSystemState (*const afEventHandler[last_State][last_Event])(void);
    

    一步一步来。

    这个

    afEventHandler[last_State][last_Event]
    

    声明一个二维数组。考虑到枚举数last_StatelastEvent 等于5 那么上面的记录就等价于

    afEventHandler[5][5]
    

    这个

    *const afEventHandler[last_State][last_Event]
    

    声明一个常量指针的二维数组(指针本身是常量)。

    最后是这个

    typedef eSystemState (*const afEventHandler[last_State][last_Event])(void);
    

    声明一个二维数组,其中包含指向eSystemState ( void ) 类型函数的常量指针。即函数返回类型为eSystemState,参数列表为void

    因此名称afEventHandler 是指向eSystemState ( void ) 类型函数的常量指针的二维数组类型的同义词

    至于这份声明

    // 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},
    };
    

    然后使用指定的初始化器声明并初始化上述类型的数组。

    这里是一个使用枚举的一维函数指针数组的类似 typedef 声明的更简化示例。

    #include <stdio.h>
    
    typedef enum { Add, Subtract, Multiply, Divide, TotalOperations } Operation;
    
    typedef int ( * const Action[TotalOperations] )( int, int );
    
    int add( int x, int y )      { return x + y; }
    int subtract( int x, int y ) { return x - y; }
    int multiply( int x, int y ) { return x * y; }
    int divide( int x, int y )   { return x / y; }
    
    int main(void) 
    {
        Action action =
        {
            [Add] = add, [Subtract] = subtract, [Multiply] = multiply, [Divide] = divide
        };
        
        int x = 100, y = 5;
        
        for ( int i = 0; i < TotalOperations; i++ )
        {
            printf( "%d\n", action[i]( x, y ) );
        }
        
        return 0;
    }
    

    程序输出是

    105
    95
    500
    20
    

    【讨论】:

    • 您好,感谢您对条款的明确细分。我最大的困惑实际上是关于StateMachine 的声明。我不知道指定的初始化程序,而且一切看起来都很笨重。
    • @learning_dude 完全没有。不客气。:)
    【解决方案2】:
    typedef eSystemState (*const afEventHandler[last_State][last_Event])(void);
    

    afEventHandler定义为一个没有参数的二维函数指针数组并返回一个eSystemState

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

    是定义类型的变量StateMachine的初始化。

     StateMachine[IdleState]
    

    然后初始化为一维指针数组,指向函数无参数,返回eSystemState

    {[Card_Insert_Event]= InsertCardHandler }
    

    一个一维数组,其索引元素Card_Insert_Event对应于函数InsertCardHandler

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-20
      • 2022-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多