C语言 - 函数指针
1.函数指针
函数指针:首先它是一个指针,一个指向函数的指针,在内存空间中存放的是函数的地址;
1.1 函数指针的定义形式
函数指针的定义: 函数的返回值类型(*指针名)(函数的参数列表类型)
1.2 函数指针的使用方法
#include <stdio.h>
//返回两个数中的最大值
int max(int a, int b) 
{
    return a > b ? a : b;
}
int main()
{
    int x = 100;
    int y = 200;
    int maxval = 0;
    //定义函数指针
    int (*pmax)(int, int) = max;  //也可以写作int (*pmax)(int a, int b)
    //使用函数指针去调用函数
    maxval = pmax(x, y); //写法1
    //maxval = (*pmax)(x, y);//写法2
    printf("Max value: %d\n", maxval);
    return 0;
}
 第 14 行代码对函数进行了调用。pmax 是一个函数指针,在前面加 * 就表示对它指向的函数进行调用。注意( )的优先级高于*,第一个括号不能省略
程序运行结果:

1.3 函数指针充当函数参数
下面实现了一个简单的回调函数
#include <stdio.h>
int Max(int a, int b)
{
	return a > b ? a : b;
}
int Min(int aa, int bb)
{
	return aa > bb ? bb : aa;
}
int Sum(int a, int b)
{
	return a + b;
}
//以函数指针充当函数参数
void callback(int(*pFun)(int, int), int a, int b)
{
	printf("%d\n", pFun(a, b));//函数指针调用
}
int main()
{
	//函数指针充当函数参数
	//回调函数: 统一接口
	callback(Max, 1,2);			//最大值
	callback(Min, 3,4);			//最小值
	callback(Sum, 1,1);			//求和
	return 0;
}
1.4 函数指针充当函数返回值
#include <stdio.h>
int Max(int a, int b)
{
	return a > b ? a : b;
}
//这样写会报错!编译器解析不了函数的返回值,需要使用typedef给函数指针起别名
//int(*p)(int, int) returnFunction(int(*pf)(int, int), int a, int b)
//{
//	return pf;
//}
//函数指针起别名
typedef int(*PFUNC)(int, int);
//函数指针充当函数返回值
PFUNC returnFunction(PFUNC pf, int a, int b)
{
    printf("%d\n", pf(a, b));
    return pf;
}
int main()
{
	PFUNC p = returnFunction(Max, 1, 2);
	printf("%d\n", p(5, 6));
	return 0;
}
1.5 使用typedef给函数指针起别名
#include <stdio.h>
//1.给简单数据类型别名
typedef int 整数;
//2.给数组起别名
typedef int ARRAY[3];
//万能看typedef语句
//1.直接用别名定义的名字替换别名
//typedef int array[3];
//2.去掉typedef 剩下就是你定义的东西
// int array[3]
typedef int ARRAY2D[2][2];
int  Max(int a, int b) 
{
	return a > b ? a : b;
}
//3.函数指针起别名
typedef int(*PFUNC)(int, int);
//函数指针充当函数参数
PFUNC returnFunction(PFUNC pf, int a, int b) 
{
	printf("%d\n", pf(a, b));
	return pf;
}
int main() 
{
	int iNum = 1;
	整数 iNum2 = 2;
	ARRAY array;		//int array[3]
	for (int i = 0; i < 3; i++) 
	{
		array[i] = i;
		printf("%d\t", array[i]);
	}
	printf("\n");
	ARRAY num[2];		//int num[2][3];
	ARRAY2D array2D;	//int array2D[2][2];
	PFUNC pf = NULL;
	//int(*pf)(int, int)=NULL;
	//很少见,基本不这样用,函数指针更多的使用方式是: 调用函数,充当函数参数
	pf = returnFunction(Max, 1, 2);
	printf("%d\n",pf(100, 200));
	//上面两句话等效下面一句话
	int result = returnFunction(Max, 1, 2)(100, 200);
	printf("%d\n", result);
	return 0;
}
1.6 复杂的函数指针
#include <stdio.h>
//void(*p)();   去掉变量名剩下就是指针: void(*)()
void print() 
{
	printf("空类型的指针充当函数指针\n");
}
int Max(int a, int b) 
{
	return a > b ? a : b;
}
int Sum(int  a, int b) 
{
	return a + b;
}
void printData(int(*pMax)(int, int), int a, int b) 
{
	printf("%d\n", pMax(a, b));
}
//void printData(int(*pMax)(int, int), int a, int b)
//void (*p)(int(*pMax)(int, int), int a, int b)
//void(*p)(int(*)(int, int),int,int)
//以一个以函数指针为参数的函数指针为参数的函数
void userPrint(void(*p)(int(*)(int, int),int,int), int(*pMax)(int, int), int a, int b) 
{
	p(pMax, a, b);
}
int main() 
{
	//1.万能指针充当函数指针
	void* pVoid = NULL;
	//使用前必须做类型转换
	pVoid = print;    //print的类型: void(*)();
	((void(*)())pVoid)();
	(*(void(*)())pVoid)();
	//2.以一个以函数指针为参数的函数指针为参数的函数
	userPrint(printData, Max, 1, 2);
	userPrint(printData, Sum, 1, 2);
	void (*pFunc)(void(*)(int(*)(int, int), int, int),
		int(*)(int, int),
		int, int) = NULL;
	pFunc = userPrint;
	pFunc(printData, Sum, 100, 200);
	//3.函数指针数组:多个函数指针的集合
	int (*pMax)(int, int) = NULL;
	int(*pArray[2])(int, int);
	typedef int(*pXX)(int, int);
	pXX X[2];
	X[0] = Max;
	X[1] = Sum;
	//int *array[2];
	pArray[0] = Max;
	pArray[1] = Sum;
	for (int i = 0; i < 2; i++) 
	{
		printf("%d\n",pArray[i](100, 200));
	}
	typedef int(*B)(int, int);
	typedef int(*C)(int, int);
	typedef void(*A)(B b, int, int);
	void (*pFunc)(A a,C c,int, int) = NULL;
	//void XXX(A a, C c,int d,int e);
	return 0;
}
2. 函数指针数组
函数指针数组可以理解为将函数指针储存进数组中,这个数组便是函数指针数组。
2.1 函数指针数组的定义
#include <stdio.h>
int Add(int x, int y)
{
	return x + y;
}
int Sub(int x, int y)
{
	return x - y;
}
 
int main()
{
	//函数指针数组的定义
	int (*Farr[2])(int x, int y) = { Add, Sub };
	//调用
	int ret = Farr[1](2, 5);
	printf("%d\n", ret);
	return 0;
}
函数指针数组的定义与数组指针数组的定义类似,我们定义的Farr先与方括号结合,形成数组,拿去数组后,剩下的便是该数组的类型,也就是函数指针。
2.2 函数指针数组的应用
我们可以利用函数指针数组完成计算器功能(转移表)
#include <stdio.h>
int Add(int x, int y)
{
	return x + y;
}
int Sub(int x, int y)
{
	return x - y;
}
int main()
{
	int input = 0;
    //我们将函数添加进函数指针数组中
	int (*Farr[])(int, int) = {0, Add, Sub };
	do
	{
		printf("请选择算法(1.Add 2.Sub 0.exit):>");
		scanf("%d", &input);
		if (input == 0)
		{
			printf("退出计算器\n");
			break;
		}
			
		if (input >= 1 && input <= 2)
		{
			int x = 0;
			int y = 0;
			printf("请输入两个操作数:>");
			scanf("%d%d", &x, &y);
            //通过调用函数指针数组使用对应的函数
			int ret = Farr[input](x, y);
			printf("%d\n", ret);
		}
		else
		{
			printf("输入有误,请重新输入\n");
		}
 
	} while (input);
	return 0;
}
使用函数指针数组后,我们可以避免switch语句的使用,是代码看起来更整洁。

                
            
        
浙公网安备 33010602011771号