C Pointer

C语言函数指针

函数指针的定义:如果在程序中定义了一个函数,在编译时,编译系统会为函数代码分配一段存储空间,而这段存储空间的起始地址(入口地址)称为这个函数的指针。

使用时,函数名就是地址,跟数组名的地址有异曲同工之妙。

那么如何定义一个函数指针。其实与普通变量一样,例如 int a, int *p; char a, char *p依次类推,函数声明:int getData(int a ,int b); 则函数指针声明int (p) (int a,int b); 其中值得注意的 是,(p)需要用括号括起来,由于优先级的原因。如果没有写括号,则实际上就写了个指针函数返回值为int *型

我们如何来使用呢,接下来我们来试一试:

实际上,函数调用概念和变量一样。

例如之前使用变量时,我们可以直接使用变量名来进行直接操作,例如int a = 1;也可以使用地址来进行间接操作。例如int *p = &a; *p = 1;等。函数调用也是如此,可以使用函数名直接调用,或者使用函数指针来间接调用。


#include "stdio.h"
void PrintWelcome()
{
    printf("Hello, welcome\n");
}

int main()
{
    // 直接函数名调用:
    PrintWelcome();
    // 定义一个函数指针来调用.
    void (*p)() = PrintWelcome;
    (*p) ();
    return 0;
}

运行结果如下:


vxbus@vxworks:~/github/code$ ./test 
Hello, welcome
Hello, welcome
vxbus@vxworks:~/github/code$ 

发现其效果是一样的。但是值得注意的是,你要定义一个函数指针来指向一个函数,那么你函数指针的数据类型,应该要与你想所指的函数的类型一致。

函数指针的好用之处

为了更好地使用函数指针,我们来做一个练习:现在有个题目:

有两个整数a和b,由用户输入1,2或3.如输入1则给出ab中大的数,如果输入2则给出小的,如果输入3则输出两数之和。

我们通过用户输入的数值不同,通过switch将不同情况将函数指针指向不同的函数。最后通过dataHandler()函数统一调用函数。


#include "stdio.h"
#include "stdlib.h"
/*
	用户输入一个数字
	通过1取最大值,2取最小值,3求和
*/
int GetMax(int data1,int data2)
{
	return data1>data2?data1:data2;
}

int GetMin(int data1, int data2)
{
	return data1 < data2 ? data1 : data2;
}

int GetSum(int data1,int data2)
{
	return data1+data2;
}

int dataHandler(int data1, int data2, int (*pfunk)(int data1, int data2))
{
	int data;
	data = (*pfunk)(data1, data2);
}

int main()
{
	int a = 10;
	int b = 20;
	int cmd;
	int ret;
	
	int (*pfunk)(int data1, int data2);
	
	printf("请输入一个数字1、取最大值  2、取最小值  3、取两数之和");
	scanf("%d", &cmd);
	
	switch(cmd){
		case 1:
			printf("最大值为:");
			pfunk = GetMax;
			break;
		case 2:
			printf("最小值为:");
			pfunk = GetMin;
			break;
		case 3:
			printf("和为:");
			pfunk = GetSum;
			break;
		default:
			printf("输入错误");
			exit(-1);
	}
	
	ret = dataHandler(a, b, pfunk);
	printf("ret =%d \n", ret);
	return 0;
}

运行结果如下:


vxbus@vxworks:~/github/code$ ./test 
请输入一个数字1、取最大值  2、取最小值  3、取两数之和1
最大值为:ret =20 
vxbus@vxworks:~/github/code$ ./test 
请输入一个数字1、取最大值  2、取最小值  3、取两数之和2
最小值为:ret =10 
vxbus@vxworks:~/github/code$ ./test 
请输入一个数字1、取最大值  2、取最小值  3、取两数之和3
和为:ret =30 
vxbus@vxworks:~/github/code$ 

通过这个案例,你能否了解到,其中的妙处。

总结

函数指针在声明时由于优先级原因,记得要加括号,不然会变成一个指针函数。

函数指针指向函数时,函数指针外形应该跟函数长得一样,其中函数指针中的形参的名字可以直接省略,例如int (*pfunk)(int data1, int data2)其中的data1和data2 可以不写直接int (*pfunk)(int, int )也是不会有错误的。