C笔记之函数指针数组的使用

为了对比函数指针的优势便于理解,举例如下:针对状态机的程序实现相当简单,第一种方法是用 swich-case 实现:
void RunTaskN() 

{

switch (state) {

case 0: state0(); break;

case 1: state1(); break;



case M: stateM(); break;

default:

state = 0;

}

}
如果利用了函数指针数组将会使上面的方式更简洁
//首先定义一个函数类型
typedef void (*FUNCTIONPTR)();
//初始化函数指针数组
const FUNCTIONPTR[] states = { state0, state1, …, stateM };
//使用
void RunTaskN()
{
(*states[state])();
}
//控制例子
void state0() { }

void state1() { state++; } // next state;

void state2() { state+=2; } // go to state 4;

void state3() { state--; } // go to previous state;

void state4() { delay = 100; state++; }

void state5() { delay--; if (delay <= 0) state++; } //delay 100*tick

void state6() { state=0; } // go to the first state
一个小技巧是把第一个状态 state0 设置为空状态,即:
void state0() { }
这样,state =0可以让整个task 停止运行,如果需要投入运行,简单的让 state = 1 即可。
已邀请:

admin

赞同来自: lLvcube

要学好C语言你还得看STM32提供的库
这俩typedef struct彻底颠覆了我对C语言知识。
typedef struct _USER_STANDARD_REQUESTS
{
void (*User_GetConfiguration)(void); /* Get Configuration */
void (*User_SetConfiguration)(void); /* Set Configuration */
void (*User_GetInterface)(void); /* Get Interface */
void (*User_SetInterface)(void); /* Set Interface */
void (*User_GetStatus)(void); /* Get Status */
void (*User_ClearFeature)(void); /* Clear Feature */
void (*User_SetEndPointFeature)(void); /* Set Endpoint Feature */
void (*User_SetDeviceFeature)(void); /* Set Device Feature */
void (*User_SetDeviceAddress)(void); /* Set Device Address */
}
USER_STANDARD_REQUESTS;
typedef struct _DEVICE_PROP
{
void (*Init)(void); /* Initialize the device */
void (*Reset)(void); /* Reset routine of this device */
/* Device dependent process after the status stage */
void (*Process_Status_IN)(void);
void (*Process_Status_OUT)(void);
/* Procedure of process on setup stage of a class specified request with data stage */
/* All class specified requests with data stage are processed in Class_Data_Setup
Class_Data_Setup()
responses to check all special requests and fills ENDPOINT_INFO
according to the request
If IN tokens are expected, then wLength & wOffset will be filled
with the total transferring bytes and the starting position
If OUT tokens are expected, then rLength & rOffset will be filled
with the total expected bytes and the starting position in the buffer
If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT
CAUTION:
Since GET_CONFIGURATION & GET_INTERFACE are highly related to
the individual classes, they will be checked and processed here.
*/
RESULT (*Class_Data_Setup)(uint8_t RequestNo);
/* Procedure of process on setup stage of a class specified request without data stage */
/* All class specified requests without data stage are processed in Class_NoData_Setup
Class_NoData_Setup
responses to check all special requests and perform the request
CAUTION:
Since SET_CONFIGURATION & SET_INTERFACE are highly related to
the individual classes, they will be checked and processed here.
*/
RESULT (*Class_NoData_Setup)(uint8_t RequestNo);
/*Class_Get_Interface_Setting
This function is used by the file usb_core.c to test if the selected Interface
and Alternate Setting (uint8_t Interface, uint8_t AlternateSetting) are supported by
the application.
This function is writing by user. It should return "SUCCESS" if the Interface
and Alternate Setting are supported by the application or "UNSUPPORT" if they
are not supported. */
RESULT (*Class_Get_Interface_Setting)(uint8_t Interface, uint8_t AlternateSetting);
uint8_t* (*GetDeviceDescriptor)(uint16_t Length);
uint8_t* (*GetConfigDescriptor)(uint16_t Length);
uint8_t* (*GetStringDescriptor)(uint16_t Length);
uint8_t* RxEP_buffer;
uint8_t MaxPacketSize;
}DEVICE_PROP;
应用分析:struct是一个结构体,可以用来构造数据类型。所以可以得知这两个struct里面的数据不是函数,而是函数指针,即它是一个指针,指向一个函数。RESULT,uint8_t*,void是函数的返回值类型。

要回复问题请先登录注册