抛砖引玉,函数指针数组的实际用途
函数指针数组是个比较复杂的概念,会用的人不多,CSDN上相关的问题也很少。从概念上分析,函数指针数组首先是一个数组,数组的元素都是函数指针,而函数指针又是一个指针,但它不是指向普通数据类型或者结构体的指针,而是一个指向函数的指针。
我的问题是,函数指针数组在实际开发中,都有些什么用途?其实,不使用函数指针数组,大部分情况都是可以使用别的方法完成的。以大家的经验和体会,是怎样灵活使用函数指针数组以提高程序的可读性和执行性能的?最好能给出代码实例。
[解决办法]
下面例子是来自我写的一篇文章,感兴趣的话可以去看看,这只是C语言应用的一个小小的技巧,其中对于一长串switch,函数指针数组也是一种选择。
#ifndef _TEST_C_
#define _TEST_C_
#include <stdio.h>
int _my_add(int,int);
int _my_sub(int,int);
int _my_mul(int,int);
int _my_div(int,int);
int _my_mod(int,int);
int main(void)
{
int number_one;
int number_two;
int number_control;
int (*function_buffer[])(int,int) = {
_my_add,_my_sub,
_my_mul,_my_div,
_my_mod
};
while(1)
{
printf("这是一个简单的计算器,主要有下面的功能!\n");
printf(" 1:加\n 2:减\n 3:乘\n 4:除\n 5:求模\n");
printf("输入格式为:num1 num2 操作\n");
scanf("%d %d %d",&number_one,&number_two,&number_control);
if(((number_control == 4) &&(!(number_two
[解决办法]
0x0)))\
[解决办法]
(number_control > 5)){
printf("input is err\n");
continue;
}
printf("Result is:%d\n",\
function_buffer[number_control - 1](number_one,number_two));
}
return 0;
}
int _my_add(int number_one,int number_two)
{
return number_one + number_two;
}
int _my_sub(int number_one,int number_two)
{
return number_one - number_two;
}
int _my_mul(int number_one, int number_two)
{
return number_one * number_two;
}
int _my_div(int number_one, int number_two)
{
return number_one / number_two;
}
int _my_mod(int number_one,int number_two)
{
return number_one % number_two;
}
#endif
typedef void (*FUN)();
//事件类型
enum EVENT_TYPE
{
EVENT_TYPE_1 = 0,
EVENT_TYPE_2,
EVENT_TYPE_3,
EVENT_TYPE_END,
};
//这里不是单纯的函数指针,稍微扩展成了一个STRUCT,为了阅读,维护更容易
struct EVENT_FUN_MAP
{
EVENT_TYPEeType;
FUNpFun;
};
//针对不同的事件,只需要修改这个就可以改变事件的动作
EVENT_FUN_MAP eFunMap[EVENT_TYPE_END] = {
EVENT_TYPE_1,&EventFun1,
EVENT_TYPE_2,&EventFun2,
EVENT_TYPE_3,&EventFun3,
}
..............................
void DoAction(EVENT_TYPE eType)
{
(*eFunMap[eType].pFun)();
}
void DoAction(EVENT_TYPE eType)
{
(*eFunMap[eType].pFun)();
}
void ReloadEventFun()
{
eFunMap[EVENT_TYPE_1].pFun = &MyEventFun1;
}
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath)
{
NTSTATUS status;
//注册其他驱动调用函数入口
pDriverObject->DriverUnload = HelloDDKUnload;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = MyDDKCreate;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = MyDDKClose;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = MyDDKWrite;
pDriverObject->MajorFunction[IRP_MJ_READ] = MyDDKRead;
.........
.........
}
#include <stdio.h>
struct Fucker_
{
#define MAX_LIST 256
int top;
void (*FuckEvent[MAX_LIST])(struct Fucker_* pThis);
};
typedef struct Fucker_ Fucker;
voidinit(Fucker* pThis)
{
pThis->top = 0;
}
voidpush(Fucker* pThis, void (*pHandler)(Fucker* p))
{
pThis->FuckEvent[pThis->top++] = pHandler;
}
voidpop(Fucker* pThis)
{
--pThis->top;
}
voiddo_fuck(Fucker* pThis)
{
int i;
for (i = 0; i < pThis->top; ++i)
(*pThis->FuckEvent[i])(pThis);
}
voidPolice(Fucker* pThis)
{
puts("catch him");
}
voidPeople(Fucker* pThis)
{
puts("come on");
}
int main()
{
Fucker a;
init(&a);
push(&a, Police);
push(&a, Police);
push(&a, People);
do_fuck(&a);
pop(&a);
do_fuck(&a);
return 0;
}
static intSet[COMMAND_NUMBERS]=
{
'AA','AC','AD','AR','AT',
'BP',
'CF','CI','CP','CR','CT',
'DC','DF','DI','DL','DP','DR','DT','DV',
'EA','EC','EP','ER','ES','EW',
'FI','FN','FP','FR','FT',
'IN','IP','IR','IW',
'LA','LB','LO','LT',
'MC','MG','MT',
'NP','NR',
'OD','OE','OH','OI','OP','OS',
'PA','PC','PD','PE','PG','PM','PR','PS','PU','PW',
'QL',
'RA','RF','RO','RP','RR','RT',
'SA','SB','SC','SD','SI','SL','SM','SP','SR','SS','ST','SV',
'TD','TR',
'UL',
'VS',
'WG','WU'
};
int InSet()
{
//wat
key=toupper(ch2)
[解决办法]
(toupper(ch1)<<8);
//bc3
//key=toupper(ch1)
[解决办法]
(toupper(ch2)<<8);
n=COMMAND_NUMBERS;
SetInUse=Set;
if (PictureBodyState==YES&&LostMode==OFF) SetInUse=SetBody;
else if (PolygonMode==ON &&LostMode==OFF) SetInUse=SetPoly;
else if (PolygonMode==OFF&&LostMode==ON) SetInUse=SetLost;
else if (PolygonMode==ON &&LostMode==ON) SetInUse=SetLostPoly;
CommandIndex=(int *)lfind(&key,SetInUse,&n,sizeof(int),(int(*)(const void *,const void *))compare);
if (CommandIndex) return YES;
else return NO;
}
//-------------------------------------------------------
if (InSet()) {
((void(*)())CommandEnterPointTable[(FP_OFF(CommandIndex)-FP_OFF(SetInUse))/sizeof(int)])();
//ignore CR,LF,SPC,Parameters that not need
do ch1=GetAChar(); while (!(isalpha(ch1)
[解决办法]
feof(fi)
[解决办法]
ch1==27));
if (feof(fi)) break; else continue;
} else {
ch1=ch2;
ErrorNumber=1;
ReportError();
continue;
}
CommandEnterPointTable[ 0]=(unsigned long)AA;
CommandEnterPointTable[ 1]=(unsigned long)AC;
void AA();
void AC();