(函数指针) 指向函数的指针
函数指针- 指向函数的指针
- 函数指针的声明和使用
- 通过函数指针调用函数
- 函数指针做参数
- 函数指针数组
函数指针的声明和使用
函数指针的声明格式:
返回值类型 (*函数指针名)(参数列表);
其中:
*函数指针名
表示函数指针的名称返回值类型
则表示该指针所指向的函数的返回值类型参数列表
则表示该指针所指向的函数的参数列表。
例如:
int func(int x,int y); //声明一个函数
fp=func;//将函数func的首地址给fp指针
int (*fp)(int, int); //声明一个函数指针
表示一个指向返回值类型为 int,参数类型为两个 int 的函数的函数指针。
- 举例:func加法
// 声明一个函数
int func(int x, int y) {
return x + y;
}
int main() {
// 声明一个函数指针
int (*fp)(int, int);
// 将函数的首地址赋给函数指针
fp = func;
// 通过函数指针调用函数
int result = (*fp)(1, 2); // result = 3
return 0;
}
在这段代码中,我们通过 fp = func; 将函数 func 的首地址赋给了函数指针 fp,然后通过 (*fp)(1, 2) 可以调用 func 函数,并将结果赋给变量 result。
通过函数指针调用函数
使用格式: (*函数指针名)(参数列表);
// 声明一个函数
int func(int x, int y) {
return x + y;
}
int main() {
// 声明一个函数指针
int (*fp)(int, int);
// 将函数的首地址赋给函数指针
fp = func;
// 通过函数指针调用函数
int result = (*fp)(1, 2); // result = 3
return 0;
}
上面函数func我们用fp指向了它,然后调用时候使用的是(*fp)(参数列表);
// 通过函数指针调用函数
int result = (*fp)(1, 2); // result = 3
函数指针做参数
函数指针作为函数参数的好处在于可以让函数接受一个函数作为输入,从而增强函数的灵活性和可重用性。通过传递不同的函数指针,可以让同
一个函数执行不同的操作,从而减少了代码的重复编写。
下面举个例子:
- 用函数指针实现带有菜单驱动的数组排序
思路如下:
- 根据三种排序要求,分别定义三个排序函数
int asc(int x,int y);//升序排序,若x>y,则视为逆序返回1
int desc(int x,int y);//降序排序,若x<y,则视为逆序返回1
int AscAbs(int x,int y);//绝对值升序排序,若fabs(x)>fabs(y)则视为逆序返回1
- 为Sort函数添加一个指向函数的指针作为形参,sort()函数原型如下:
void Sort(int arr[],int n,int(*f)(int x,int y));
这样就定义了一个sort函数,通过调用形参指针f所指向的函数来比较二个元素的关系(是否逆序),判断是否需要交换。
- 在调用sort函数时,根据不同的排序要求,选择不同的比较函数作为实参,例如下面:
Sort(a,n,asc);
具体代码如下:
#include<stdio.h>
#include<math.h>
int asc(int x,int y);//升序排序,若x>y,则视为逆序返回1
int desc(int x,int y);//降序排序,若x<y,则视为逆序返回1
int AscAbs(int x,int y);//绝对值升序排序,若fabs(x)>fabs(y)则视为逆序返回1
void Sort(int arr[],int n,int(*f)(int x,int y));
int main()
{
int a[5]={3,-4,1,5,2};
int select;
int n=5,i;
//菜单
while (1)
{
printf("1.升序\n");
printf("2.降序\n");
printf("3.按绝对值升序\n");
printf("0.退出\n");
printf("请做出你的选择\n");
scanf("%d",&select);
if(select==0)
break;
if(select<0&&select>3)
printf("请输入正确的选项\n");
//根据用户的选择,调用不同的比较函数
switch (select)
{
case 1: Sort(a,n,asc);break;
case 2: Sort(a,n,desc);break;
case 3: Sort(a,n,AscAbs);break;
default:
break;
}
for ( i = 0; i < 5; i++)
{
printf("%d ",a[i]);
printf("\n");
}
}
return 0;
}
int asc(int x,int y)
{
if(x>y)
return 1;
else
return 0;
}
int desc(int x,int y)
{
if(x<y)
return 1;
else
return 0;
}
int AscAbs(int x,int y)
{
if(fabs(x)>fabs(y))
return 1;
else
return 0;
}
void Sort(int arr[],int n,int(*f)(int x,int y))
{
int i,j,t;
//冒泡排序
for(i=0;i<n-1;i++)
{
for(j=0;j<n-i-1;j++)
{
if((*f)(arr[j],arr[j+1]))//逆序返回1
{
t=arr[j];
arr[j]=arr[j+1];
arr[j+1]=t;
}
}
}
}
函数指针数组
我们可以把函数指针作为数组元素。比如你需要完成上面类似的选择操作,那么你就可以把这些函数用函数指针数组指向
- 格式:
返回类型 (*指针数组名[数组长度])(形参列表);
类似: int (*f[])(int x, int y)={asc,desc,AscAbs};
- 改进上面那个程序,变为函数指针数组形式
#include<stdio.h>
#include<math.h>
int asc(int x, int y);//升序排序,若x>y,则视为逆序返回1
int desc(int x, int y);//降序排序,若x<y,则视为逆序返回1
int AscAbs(int x, int y);//绝对值升序排序,若fabs(x)>fabs(y)则视为逆序返回1
void Sort(int arr[], int n, int(*f)(int x, int y));
int main()
{
int (*f[])(int x, int y) = {asc, desc, AscAbs};
int a[5] = {3, -4, 1, 5, 2};
int select;
int n = 5, i;
//菜单
while (1)
{
printf("1.升序\n");
printf("2.降序\n");
printf("3.按绝对值升序\n");
printf("0.退出\n");
printf("请做出你的选择\n");
scanf("%d", &select);
if (select == 0)
break;
if (select < 0 || select > 3)
{
printf("请输入正确的选项\n");
continue;
}
printf("排序前: ");
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("\n");
Sort(a, n, f[select - 1]);
printf("排序后: ");
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
return 0;
}
int asc(int x, int y)
{
if (x > y)
return 1;
else
return 0;
}
int desc(int x, int y)
{
if (x < y)
return 1;
else
return 0;
}
int AscAbs(int x, int y)
{
if (fabs(x) > fabs(y))
return 1;
else
return 0;
}
void Sort(int arr[], int n, int(*f)(int x, int y))
{
int i, j, t;
//冒泡排序
for (i = 0; i < n - 1; i++)
{
for (j = 0; j < n - i - 1; j++)
{
if ((*f)(arr[j], arr[j + 1]))//逆序返回1
{
t = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = t;
}
}
}
}
在这个例子中,定义了一个函数指针数组f[],可以按照数组下标从0到2的顺序存储三个不同的函数指针。每个函数指针都是指向不同的比较函数,即asc()、desc()和AscAbs()。
在主函数中,通过菜单的形式让用户进行选择,然后调用不同的比较函数来进行排序。具体来说,根据用户的选择,索引相应的函数指针,然后调用Sort()函数来进行排序。在调用Sort()函数时,直接把函数指针作为参数传递给函数,就可以根据用户的选择来决定使用哪个比较函数进行排序。
最后,可以看到在Sort()函数中,调用了函数指针所指向的函数,因为函数指针本身并没有实现函数的功能,只是指向函数的地址。而在具体的排序过程中,需要使用到函数指针所指向的函数的功能,因此需要通过函数指针来调用相应的函数。