关于- 函数指针数组的妙用(替代switch-case)

函数指针数组

函数名可以通过函数指针加以保存,那们也一定能定义一个数组保存若干个函数名,这就是函数指针数组。正确使用函数指针数组的前提条件是,这若干个需要通过函数指针数组保存的函数必须有相同的输入、输出值。

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使用

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值