当前位置: 首页 > article >正文

(函数指针) 指向函数的指针

函数指针- 指向函数的指针

  • 函数指针的声明和使用
  • 通过函数指针调用函数
  • 函数指针做参数
  • 函数指针数组

函数指针的声明和使用

函数指针的声明格式:
返回值类型 (*函数指针名)(参数列表);

其中:

  • *函数指针名 表示函数指针的名称
  • 返回值类型 则表示该指针所指向的函数的返回值类型
  • 参数列表 则表示该指针所指向的函数的参数列表。

例如:

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

函数指针做参数

函数指针作为函数参数的好处在于可以让函数接受一个函数作为输入,从而增强函数的灵活性和可重用性。通过传递不同的函数指针,可以让同 一个函数执行不同的操作,从而减少了代码的重复编写。

下面举个例子:

  • 用函数指针实现带有菜单驱动的数组排序

思路如下:

  1. 根据三种排序要求,分别定义三个排序函数
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
  1. 为Sort函数添加一个指向函数的指针作为形参,sort()函数原型如下:
void Sort(int arr[],int n,int(*f)(int x,int y));

这样就定义了一个sort函数,通过调用形参指针f所指向的函数来比较二个元素的关系(是否逆序),判断是否需要交换。

  1. 在调用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()函数中,调用了函数指针所指向的函数,因为函数指针本身并没有实现函数的功能,只是指向函数的地址。而在具体的排序过程中,需要使用到函数指针所指向的函数的功能,因此需要通过函数指针来调用相应的函数。



http://www.kler.cn/a/9568.html

相关文章:

  • vue elementui el-dropdown-item设置@click无效的解决方案
  • Axure是什么软件?全方位解读助力设计入门
  • SpringCloud框架学习(第二部分:Consul、LoadBalancer和openFeign)
  • day60 图论章节刷题Part10(Floyd 算法、A * 算法)
  • 【安全测试】sqlmap工具(sql注入)学习
  • 【LLM】3:从零开始训练大语言模型(预训练、微调、RLHF)
  • cephadm离线部署及curushmap
  • 2023年全国最新保安员精选真题及答案48
  • 打怪升级之FPGA组成原理(LE部分)
  • 关于linux的chnod问题
  • 让代码变得优雅简洁的神器:Java8 Stream流式编程
  • [自注意力神经网络]Segment Anything(SAM)论文阅读
  • 如何避免 MyBatis 查询导致的内存溢出:配置与策略指南
  • Python-代码阅读-图像处理的类 ImageProcess
  • pc端页面嵌入,同源,app无内容,页面空白问题(vite)
  • 微信小程序引入骨架屏
  • pinia的使用以及持久化存储
  • JS中的宏任务与微任务
  • 壁纸保存下
  • MLOps : 机器学习运维
  • 入门IC必读书目,你想知道的都在这里
  • Nacos在derby模式下如何更改密码?
  • 算法每日一题:P2089 烤鸡 -DFS练习
  • 学生台灯哪个品牌的专业?盘点小学生台灯品牌排行榜
  • 如何用 YonBuilder 构建线索管理应用
  • 【hello Linux】Linux软件管理器yum