鱼C论坛

 找回密码
 立即注册
查看: 2302|回复: 5

[已解决]关于函数指针

[复制链接]
发表于 2023-1-3 12:14:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <stdio.h>

int add(int, int);
int sub(int, int);
int calc(int (*fp)(int, int), int, int);
int (*select(char op))(int, int);

int add(int num1, int num2)
{
        return num1 + num2;
}

int sub(int num1, int num2)
{
        return num1 - num2;
}

int calc(int (*fp)(int, int), int num1, int num2)
{
        return (*fp)(num1, num2);
}

int (*select(char op))(int, int)
{
        switch(op)
        {
                case '+': return add;
                case '-': return sub;
        }
}

int main()
{
        int num1, num2;
        char op;
        int (*fp)(int, int);

        printf("请输入一个式子(如:1+2):");
        scanf("%d%c%d", &num1, &op, &num2);

        fp = select(op);// 想问一下,不是说函数名字就是地址吗?前面小甲鱼讲函数指针的时候就是直接将函数名字赋给指针变量的(对应课程p30 13:48处,fp=square),按照前面讲的规则,不是应该fp=select吗?为什么这里要带上(op)呀(我试过去掉(op),程序无法正常运行,但是想问一下大家这是为啥?)
        printf("%d %c %d = %d\n", num1, op, num2, calc(fp, num1, num2));

        return 0;
}
最佳答案
2023-1-3 12:34:29
#include <stdio.h>

int add(int, int);
int sub(int, int);
int calc(int (*fp)(int, int), int, int);
int (*select(char op))(int, int);

int add(int num1, int num2)
{
        return num1 + num2;
}

int sub(int num1, int num2)
{
        return num1 - num2;
}

int calc(int (*fp)(int, int), int num1, int num2)
{
        return (*fp)(num1, num2);
}

int (*select(char op))(int, int)
{
        switch(op)
        {
                case '+': return add;
                case '-': return sub;
        }
}

int main()
{
        int num1, num2;
        char op;
        int (*fp)(int, int);                            // 这个是要select函数的返回值
        int (*(*fps)(char op))(int num1, int num2);     // 这个才是要select函数的地址

        printf("请输入一个式子(如:1+2):");
        scanf("%d%c%d", &num1, &op, &num2);

        fp = select(op);
        printf("%d %c %d = %d\n", num1, op, num2, calc(fp, num1, num2));

        // 这可能是你想要的那种情况
        fps = select;   // 先把select函数的地址给fps变量
        fp = fps(op);   // 用fps这个变量来调用select函数,参数是上面输入的op变量,调用fps函数得到的返回值给fp变量
        printf("%d %c %d = %d\n", num1, op, num2, calc(fp, num1, num2));

        // select函数的返回值要么是add函数的地址,要么是sub函数的地址
        // 像下面这样
        // 不过这是直接在代码里面写死了
        // 如果调用select函数的话,select函数会根据传入的op参数来决定是把add函数的地址给fp,还是把sub函数的地址给fp
        fp = add;
        printf("%d %c %d = %d\n", num1, op, num2, calc(fp, num1, num2));

        fp = sub;
        printf("%d %c %d = %d\n", num1, op, num2, calc(fp, num1, num2));

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-1-3 12:19:44 | 显示全部楼层
这个fp的值不是select函数的地址,注意看select函数的返回值类型,是个函数指针
fp的值是select函数的返回值
也就是
case '+': return add;
case '-': return sub;
fp要么是add函数的地址,要么是sub函数的地址
这需要根据select传入的这个op来决定
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-3 12:21:52 From FishC Mobile | 显示全部楼层
因为 fp 想要的不是 select 函数,而是 select 函数选择的函数
select 是一个高阶函数,根据给定的运算符通过返回值指派进行对应操作的函数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-3 12:27:46 | 显示全部楼层
再结合这个代码,看看能不能理解
 #include <stdio.h>

int add(int, int);
int sub(int, int);
int calc(int (*fp)(int, int), int, int);
int (*select(char op))(int, int);

int add(int num1, int num2)
{
        return num1 + num2;
}

int sub(int num1, int num2)
{
        return num1 - num2;
}

int calc(int (*fp)(int, int), int num1, int num2)
{
        return (*fp)(num1, num2);
}

int (*select(char op))(int, int)
{
        switch(op)
        {
                case '+': return add;
                case '-': return sub;
        }
}

int main()
{
        int num1, num2;
        char op;
        int (*fp)(int, int);                            // 这个是要select函数的返回值
        int (*(*fps)(char op))(int num1, int num2);     // 这个才是要select函数的地址

        printf("请输入一个式子(如:1+2):");
        scanf("%d%c%d", &num1, &op, &num2);

        fp = select(op);
        printf("%d %c %d = %d\n", num1, op, num2, calc(fp, num1, num2));

        // 这可能是你想要的那种情况
        fps = select;   // 先把select函数的地址给fps变量
        fp = fps(op);   // 用fps这个变量来调用select函数,参数是上面输入的op变量,调用fps函数得到的返回值给fp变量
        printf("%d %c %d = %d\n", num1, op, num2, calc(fp, num1, num2));

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2023-1-3 12:34:29 | 显示全部楼层    本楼为最佳答案   
#include <stdio.h>

int add(int, int);
int sub(int, int);
int calc(int (*fp)(int, int), int, int);
int (*select(char op))(int, int);

int add(int num1, int num2)
{
        return num1 + num2;
}

int sub(int num1, int num2)
{
        return num1 - num2;
}

int calc(int (*fp)(int, int), int num1, int num2)
{
        return (*fp)(num1, num2);
}

int (*select(char op))(int, int)
{
        switch(op)
        {
                case '+': return add;
                case '-': return sub;
        }
}

int main()
{
        int num1, num2;
        char op;
        int (*fp)(int, int);                            // 这个是要select函数的返回值
        int (*(*fps)(char op))(int num1, int num2);     // 这个才是要select函数的地址

        printf("请输入一个式子(如:1+2):");
        scanf("%d%c%d", &num1, &op, &num2);

        fp = select(op);
        printf("%d %c %d = %d\n", num1, op, num2, calc(fp, num1, num2));

        // 这可能是你想要的那种情况
        fps = select;   // 先把select函数的地址给fps变量
        fp = fps(op);   // 用fps这个变量来调用select函数,参数是上面输入的op变量,调用fps函数得到的返回值给fp变量
        printf("%d %c %d = %d\n", num1, op, num2, calc(fp, num1, num2));

        // select函数的返回值要么是add函数的地址,要么是sub函数的地址
        // 像下面这样
        // 不过这是直接在代码里面写死了
        // 如果调用select函数的话,select函数会根据传入的op参数来决定是把add函数的地址给fp,还是把sub函数的地址给fp
        fp = add;
        printf("%d %c %d = %d\n", num1, op, num2, calc(fp, num1, num2));

        fp = sub;
        printf("%d %c %d = %d\n", num1, op, num2, calc(fp, num1, num2));

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-1-3 17:23:04 | 显示全部楼层
明白啦!!!谢谢大佬噢!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-17 15:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表