使用原因
如果1個switch有多個case,或是有多個if-else語句,不利于程式的閱讀和擴充。改進方法可以使用函數指針數組的方式替換。
一、函數指針數組
文章目錄
- 使用原因
- 一、函數指針數組
- 總結
一、函數指針數組
直接上代碼
#include <stdio.h>
#include <stdlib.h>
#define SUCCESS 0
#define ERROR -1
#define SIZE(a) ((sizeof(a)) / (sizeof(a[0]))) //表的大小
typedef struct
{
int event_id; //event名稱
void *data; //event的資料
int datalen; //event資料長度
} event_ind;
typedef int (*event_func)(event_ind *); /* 主動上報函數類型 */
typedef struct {
int event_id; /* event名稱 */
event_func event_func; /* event處理 */
} event_type;
typedef enum {
/* RING */
EVENT_RING = 0,
/* ^SIMHOTPLUG */
EVENT_SIM_HOT_PLUG,
EVENT_END
} event_id_e_type;
int RingEvent(event_ind* ind)
{
printf("ring event\n");
return SUCCESS;
}
int SimHotPlugEvent(event_ind *ind)
{
printf("sim hot plug event\n");
return SUCCESS;
}
/* 上報EVENT */
static event_type g_event_ind[] = {
{ EVENT_RING, RingEvent },
{ EVENT_SIM_HOT_PLUG, SimHotPlugEvent }
};
event_type *event_get(int event_id)
{
unsigned int i;
printf("需要查找的event id:%d\n", event_id);
printf("開始從表中查找支援的event id \n");
for (i = 0; i < SIZE(g_event_ind); i++) {
if(event_id == g_event_ind[i].event_id) {
printf("查找到了 %d\n",g_event_ind[i].event_id);
return &g_event_ind[i];
}
}
printf("表中沒查到event id\n");
return NULL;
}
void init_event(event_ind * ind)
{
int id;
scanf("%d",&id);
printf("id is %d\n",id);
ind->event_id = id;
printf("event_id is %d\n",ind->event_id);
ind->data = NULL;
ind->datalen = 0;
}
int main()
{
event_type *event = NULL;
event_ind *ind;
// event_ind temp;
int ret;
// ind = &temp; //結構體指針指派,直接給了局部變量的棧空間,也可以malloc
ind = (event_ind *)malloc(sizeof(event_ind));
memset(ind, 0, sizeof(*ind));
/* 2021.4.8 沒驗證 */
ind->data = (void *)malloc(strlen(data)); //如果data是結構體,需要sizeof()
memset(ind->data, 0, strlen(data));
/* 2021.4.8 沒驗證 */
/* event資料的初始化 */
init_event(ind);
printf("init end\n");
/* 從表中查找支援的事件 */
event = event_get(ind->event_id);
if (event == NULL) {
return ERROR;
}
/* 處理上報事件event */
ret = event->event_func(ind);
if(ret != SUCCESS) {
return ERROR;
}
/* 2021.4.8 沒驗證 */
if(ind->data) {
free(ind->data);
}
/* 2021.4.8 沒驗證 */
free(ind);
}
總結
需要注意的點
1、event處理函數的形式要和函數指針的定義相同
2、結構體指針的指派
3、表-也就是函數指針數組的定義要和結構體一緻。
修改:ind->data也有空間,申請也需要申請,代碼需要修改。釋放也是先釋放ind->data,再釋放ind。