白影嗷 发表于 2023-1-3 12:14:32

关于函数指针

#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:19:44

这个fp的值不是select函数的地址,注意看select函数的返回值类型,是个函数指针
fp的值是select函数的返回值
也就是
case '+': return add;
case '-': return sub;
fp要么是add函数的地址,要么是sub函数的地址
这需要根据select传入的这个op来决定

dolly_yos2 发表于 2023-1-3 12:21:52

因为 fp 想要的不是 select 函数,而是 select 函数选择的函数
select 是一个高阶函数,根据给定的运算符通过返回值指派进行对应操作的函数

人造人 发表于 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;
}

人造人 发表于 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;
}

白影嗷 发表于 2023-1-3 17:23:04

明白啦!!!谢谢大佬噢!!!
页: [1]
查看完整版本: 关于函数指针