函数指针数组
函数名可以通过函数指针加以保存,那们也一定能定义一个数组保存若干个函数名,这就是函数指针数组。正确使用函数指针数组的前提条件是,这若干个需要通过函数指针数组保存的函数必须有相同的输入、输出值。
int(*parr1[10])();
parr1先和[]结合,说明parr1是数组,数组的内容是int(*)()类型的函数指针
函数指针数组的用途:转移表
案例1-命令解析优化
void MyFuntion( char* buffer, int length )
{
uint8_t nStreamType = buffer[0];
switch( nStreamType )
{
case 0:
function1();
break;
case 1:
......
case 255:
function255();
break;
}
}
如果按照这种方法写下去,那么在我的每一个函数里面,都必须作如此多的判断,写出的代码肯定很长,
并且每一次处理,都要作许多次判断之后才找到正确的处理函数,代码的执行效率也不高。针对上述问题,
可以用函数指针数组的方法解决这个问题。
函数指针的概念,在潭浩强先生的C语言程序设计这本经典的教程中提及过,在大多数情况下我们使用不到,
也忽略了它的存在。函数名实际上也是一种指针,指向函数的入口地址,但它又不同于普通的如int*、double*指针,
看下面的例子来理解函数指针的概念:
int funtion( int x, int y );
void main ( void )
{
int (*fun) ( int x, int y );
int a = 10, b = 20;
function( a, b );
fun = function;
(*fun)( a, b );
……
}
语句1定义了一个函数function,其输入为两个整型数,返回也为一个整型数(输入参数和返回值可为其它任何数据类型);
语句3定义了一个函数指针,与int或double定义指针不同的是,函数指针的定义必须同时指出输入参数,表明这是一个函数指针,并且fun也必须用一对括号括起来;
语句6将函数指针赋值为funtion,前提条件是fun和function的输入参数和返回值必须保持一致。语句5直接调用函数function(),语句7是调用函数指针,二者等效。
当然从上述例子看不出函数指针的优点,目的主要是想引出函数指针数组的概念。我们从上面例子可以得知,既然函数名可以通过函数指针加以保存,
那们也一定能定义一个数组保存若干个函数名,这就是函数指针数组。
正确使用函数指针数组的前提条件是,这若干个需要通过函数指针数组保存的函数必须有相同的输入、输出值。
首先定义256个处理函数(及其实现)。
void funtion0( void );
……
void funtion255(void );
其次定义函数指针数组,并给数组赋值。
void (*fun[256])(void);
fun[0] = function0;
……
fun[255] = function();
最后,MyFunction()函数可以修改如下:
void MyFuntion( char* buffer, int length )
{
__int8 nStreamType = buffer[0];
(*fun[nStreamType])();
}
只要2行代码,就完成了256条case语句要做的事,减少了编写代码时工作量,将nStreamType作为数组下标,直接调用函数指针,
从代码执行效率上来说,也比case语句高。假如多个函数中均要作如此处理,函数指针数组更能体现出它的优势。
案例2 -原始计算器
#include <stdio.h>
int do_add(int a, int b)
{
printf("---------%s-------------\n", __FUNCTION__);
return a + b;
}
int do_sub(int a, int b)
{
printf("---------%s-------------\n", __FUNCTION__);
return a - b;
}
int do_mul(int a, int b)
{
printf("---------%s-------------\n", __FUNCTION__);
return a * b;
}
int do_div(int a, int b)
{
printf("---------%s-------------\n", __FUNCTION__);
return a / b;
}
int do_choose(void)
{
printf("****************************\n");
printf("please input cmd :\n");
printf("1:add 2:sub 3:mul 4:div 0:quit \n");
return 0;
}
//先定义函数指针类型;在通过指针类型定义函数指针数组
typedef int (*func) (int, int);
func fun_array[4] = {do_add, do_sub, do_mul, do_div};
int main(int argc, char const *argv[])
{
int cmd;
int i, j;
int ret;
do {
do_choose();
scanf("%d", &cmd);
if (cmd >= 1 && cmd <= 4 )
{
printf("please input two number: ");
scanf("%d%d", &i, &j);
ret = fun_array[cmd - 1](i, j);
printf("ret = %d\n", ret);
}
} while (cmd);
return 0;
}
作用
可代替switch-case使用