C函数指针
目标
在本文章中,您将学习C函数指针,这是一种特殊的指针,它指向函数而不是数据对象。
C函数指针的定义
函数指针是指向函数地址的指针。
C函数指针语法
下面演示了声明函数指针的语法:
< 返回类型 > (* < 指针名 >) (函数参数);
声明函数指针的语法与声明函数的语法类似。唯一的区别是,不是使用函数名,而是使用圆括号()中的指针名。
让我们更详细地检查上面的函数指针语法:
首先,指定函数指针的返回类型。它可以是任何有效类型,如int、float、char或void。
其次,将函数指针的名称放在括号内。按照约定,函数指针的名称以fp开头。
第三,用相应的类型指定函数的所有参数。注意,函数指针只能引用具有相同签名的函数。它意味着函数指针所指向的所有函数必须具有相同的返回类型和形参。
下面的例子声明了一个函数指针,该指针指向一个接受两个整型参数并返回一个整型数的函数。
int (*fpFunc)(int x,int y); // 声明一个函数指针
使用函数指针
在使用函数指针之前,你需要给它分配一个函数的地址。
首先,假设您有一个compare()函数,它接受两个整数a和b。如果a > b, compare()函数返回1,如果a = b,返回0,如果a < b,返回-1。
下面是compare()函数的声明和实现:
int compare(int,int);
/*
目的: 比较x和y
返回 1 如果 x > y, -1 如果 x < y , 0 如果 x = y */
int compare(int x,int y)
{
if(x > y)
return 1;
if(x < y )
return -1;
return 0;
}
接下来,我们声明一个函数指针,该指针指向compare()函数:
int (*fpComparer)(int x,int y);
然后,在main()函数内部,可以将compare()函数的地址赋值给函数指针:
fpComparer =&compare;
注意,一元操作符&是可选的。然而,为了使代码更易于移植,当将函数的地址赋给函数指针时,应该始终使用一元操作符(&)。
最后,我们可以使用函数指针调用函数,如下所示:
result = (*fpComparer)(a,b);
全部放在一起。
#include <stdio.h>
#include <stdlib.h>
/* 声明一个函数指针 */
int (*fpComparer)(int x,int y);
int compare(int,int);
int main()
{
int result;
int a = 10;
int b = 20;
char* msg;
fpComparer = &compare;
result = (*fpComparer)(a,b);
switch(result)
{
case 1:
printf("a大于b");
break;
case -1:
printf("a小于b");
break;
case 0:
printf("a等于b");
break;
}
return 0;
}
/*
目的: 比较x和y
返回 1 如果 x > y, -1 如果 x < y , 0 如果 x = y */
int compare(int x,int y)
{
if(x > y)
return 1;
if(x < y )
return -1;
return 0;
}
将函数指针作为参数传递给函数
你可以将函数指针作为参数传递给函数。这允许您使代码更加灵活。使用函数指针作为参数的一个经典例子是函数库中的qsort()函数。函数的作用是:使用快速排序算法对任意类型的数组进行排序。
下面的示例演示如何使用qsort()函数对整数数组进行排序。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare_int(const int * x,const int * y);
int (*fpComparer)(const void *p, const void *q);
int main()
{
int i;
// 排序整型数组
int int_arr[] = { 7, 3, 4, 1, -1, 23, 12, 43, 2, -4, 5 };
size_t len = sizeof(int_arr)/sizeof(int);
fpComparer = &compare_int;
qsort(int_arr, len, sizeof(int), (*fpComparer));
// 打印排序后的数组
for(i = 0; i < len; i++)
{
printf("%d ",int_arr[i]);
}
printf("\n");
}
int compare_int(const int * x,const int * y)
{
if (*x == *y)
return 0;
else if (*x < *y)
return -1;
else
return 1;
}
返回函数指针的函数
函数可以返回函数指针。让我们看一下下面的例子:
#include <stdio.h>
#include <stdlib.h>
/* 定义函数指针类型 */
typedef int(*pfOperator)(int, int);
int plus(int,int);
int minus(int,int);
pfOperator getOperator(const char oper);
int main()
{
int x = 10,
y = 20,
z = 0;
pfOperator func = NULL;
func = getOperator('+');
z = func(x,y);
printf("%d\n",z);
func = getOperator('-');
z = func(x,y);
printf("%d\n",z);
return 0;
}
pfOperator getOperator(const char oper)
{
switch(oper)
{
case '+':
return plus;
break;
case '-':
return minus;
break;
default:
return NULL;
}
}
int plus(int x,int y)
{
return x + y;
}
int minus(int x,int y)
{
return x - y;
}
函数指针数组
函数指针数组包括具有相同签名的所有函数指针。函数指针数组允许您选择在运行时执行哪个函数。
下面的示例演示如何使用函数指针数组。
#include <stdio.h>
#include <stdlib.h>
/* define function pointer type */
typedef int(*pfOperator)(int, int);
int plus(int,int);
int minus(int,int);
pfOperator getOperator(const char oper);
int main()
{
int x = 10,
y = 20,
z = 0;
// 声明函数指针数组
pfOperator funcs[2];
funcs[0] = getOperator('+');
z = (funcs[0])(x,y);
printf("%d\n",z);
funcs[1] = getOperator('-');
z = (*funcs[1])(x,y);
printf("%d\n",z);
return 0;
}
pfOperator getOperator(const char oper)
{
switch(oper)
{
case '+':
return plus;
break;
case '-':
return minus;
break;
default:
return NULL;
}
}
int plus(int x,int y)
{
return x + y;
}
int minus(int x,int y)
{
return x - y;
}
总结
- 在本文章中,我们讨论了C函数指针,并向您展示了如何使用函数指针使代码更加灵活。