使用原因
如果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。