C语言 函数指针和参数

7xzttuei  于 2023-10-16  发布在  其他
关注(0)|答案(3)|浏览(99)

我一直试图理解geeksforgeeks的一篇文章,但无法理解代码片段。下面是一个例子:
https://www.geeksforgeeks.org/returning-a-function-pointer-from-a-function-in-c-cpp/
在这篇文章中,他们给予和示例代码如下:
基于以下代码

#include <stdio.h>
 
int add(int a, int b) {
    return a + b;
}
 
int subtract(int a, int b) {
    return a - b;
}
 
int (*operation(char op))(int, int) {
    if (op == '+') {
        return &add;
    } else if (op == '-') {
        return &subtract;
    } else {
        return NULL;
    }
}
 
int main() {
    int (*func_ptr)(int, int) = operation('+');
    printf("%d\n", func_ptr(4, 5));
    return 0;
}

我不明白一个函数是如何被这样声明的。根据我对函数指针的了解,函数指针可以这样声明:

int func(int x, int y){
     return x*y;
}

int (*func_ptr) (int, int);
func_ptr = &func;

从帖子中的描述也不是很清楚:
在这个例子中,我们有两个函数add()和subtract(),它们接受两个整数参数并返回一个整数值。我们还有一个名为operation()的函数,它接受一个字符参数op,并根据op的值返回一个函数指针,指向add()或subtract()。最后,在main()中,我们以“+”作为参数调用operation(),并将结果存储在一个名为func_ptr的函数指针中。然后我们调用func_ptr(),参数为4和5,并将结果打印到控制台。
任何帮助将不胜感激!

o7jaxewo

o7jaxewo1#

好吧,这只是当你想返回一个函数指针时C语法的工作方式。
不知道这是否会使它更清楚,但它试图解释声明的各个部分的含义:

int (*operation(char op))(int, int) 
      \-------/
        Name of this function

int (*operation(char op))(int, int) 
               \-------/
            Arguments for this function

int (*operation(char op))(int, int) 
    ^^                  ^^        ^
    This function returns a function pointer

int (*operation(char op))(int, int) 
                         \---------/
                              The argument types taken by the function the
                              function pointer points to.

int (*operation(char op))(int, int) 
\-/
 The return type of the function the function pointer points to.

语法可以使用typedef来简化,如:

typedef int (*func_pointer)(int, int);

func_pointer operation(char op) {
    ...
}
wlzqhblo

wlzqhblo2#

解构:按照建议的顺序从令牌中读取:

  • operation//这是令牌,现在看右边
  • operation(char op)//“operation”是一个函数(接受一个char参数)
  • (*operation(char op))//现在离开。看起来“操作”返回了某种指针
  • (*operation(char op))(int, int)//啊!返回一个指针,指向一个接受两个int s的函数
  • int (*operation(char op))(int, int) {// THAT函数返回int

都在这了
你已经添加了你对“它应该是什么样子”的理解。请注意,这正是在定义(和使用)指向operation的指针时在main()中出现的内容。

yrwegjxp

yrwegjxp3#

你必须用类似代数的观点来看待这个问题;)
一个函数由在某处声明的名称标识。就像变量一样。
使用typedef可以使事情更容易阅读,只要你有许多具有相同签名的函数。情况并非总是如此。但它可以为你保存大量的打字工作。

示例:虚拟功能表VFT

我将展示另一个例子。我在这里的想法是说明operation函数可以在数组中抽象。这在系统编程和一般的OOP代码中是必不可少的。或者用JavaScript将函数与事件关联起来的方式,即所谓的回调函数(callback functions)。
这个数组被称为VFT,虚拟函数表。
使用这样的东西比在GFG中编写这样的东西要快得多,也更聪明:

int (*operation(char op))(int, int) {
    if (op == '+') {
        return &add;
    } else if (op == '-') {
        return &subtract;
    } else {
        return NULL;
    }
}

为什么呢?

  • operation()本身就是一个被调用的函数。
  • 总是测试同样的东西得到同样的结果
  • 例如,+将始终返回add
  • 只有这样,才会有另一个函数调用所需的操作:
int (*func_ptr)(int, int) = operation('+');
    printf("%d\n", func_ptr(4, 5));

一个简短的例子

结果

Operands are '42' and '17'
                For operation '+' we have 42+17 = 59
                For operation '-' we have 42-17 = 25

                [using typedef] For operation '-' we have 42-17 = 25

代码

#include <stdio.h>

int add(int, int);
int subtract(int, int);

typedef int (*t_VFT)(int, int);

int main(void)
{
    int (*VFT[256])(int, int) = {0};
    VFT['+'] = add;
    VFT['-'] = subtract;

    int  oper1 = 42;
    int  oper2 = 17;
    char op    = 0;
    printf(
        "\t\tOperands are '%d' and '%d'\n", oper1, oper2);

    op = '+';
    printf(
        "\t\tFor operation '%c' we have %d%c%d = %d\n", op,
        oper1, op, oper2, VFT[op](oper1, oper2));

    op = '-';
    printf(
        "\t\tFor operation '%c' we have %d%c%d = %d\n", op,
        oper1, op, oper2, VFT[op](oper1, oper2));

    t_VFT other_VFT[12];  // just an example using typedef
    other_VFT[11] = subtract;
    int res       = other_VFT[11](oper1, oper2);
    printf(
        "\n\t\t[using typedef] For operation '%c' we have %d%c%d = %d\n", '-',
        oper1, '-', oper2, res);

    return 0;
}

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }

// https://stackoverflow.com/questions/77161800
// /function-pointers-and-argurments

总之

这是正在建造的VFT:

int (*VFT[256])(int, int) = {0};
    VFT['+'] = add;
    VFT['-'] = subtract;

这是正在使用的VFT:

op = '-';
    printf(
        "\t\tFor operation '%c' we have %d%c%d = %d\n", op,
        oper1, op, oper2, VFT[op](oper1, oper2));

注意:

  • int result = VFT[op](oper1,oper2)调用ALWAYS所需的函数。
  • 该表可以随意改变,因此可以任意更换功能。operation()的情况并非如此:
int (*operation(char op))(int, int) {
  if (op == '+') {
      return &add;
  } else if (op == '-') {
      return &subtract;
  } else {
      return NULL;
  }
}

我们需要重新编译代码来改变任何东西

相关问题