如果传递的函数也将函数作为参数,如何将函数作为参数传递给C中的函数?

Lan*_*ard 3 c pointers function parameter-passing

所以这个简单的情况只是3在传递函数时打印出来:

#include <stdio.h>

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

int
case_1_fn_a(int fn_x(int, int)) {
  return fn_x(1, 2);
}

int
main() {
  int x = case_1_fn_a(add);
  printf("%d\n", x);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是现在我想将一个函数传递给一个函数。我怎么做?

#include <stdio.h>

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

int
case_2_fn_a(int fn_x(int, int), int fn_y(int, int)) {
  return add(fn_x(add, add), fn_y(add, add));
}

int
case_2_fn_b(int fn_x(int, int)) {
  return fn_x(1, 2);
}

int
main() {
  int x = case_2_fn_a(case_2_fn_b, case_2_fn_b);
  printf("%d\n", x);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是我遇到了这些错误(如果尝试调整此错误,则会得到各种各样的错误,因此没有任何效果):

tmp.c:11:19: warning: incompatible pointer to integer conversion passing 'int (int, int)' to parameter of type 'int' [-Wint-conversion]
  return add(fn_x(add, add), fn_y(add, add));
                  ^~~
tmp.c:11:24: warning: incompatible pointer to integer conversion passing 'int (int, int)' to parameter of type 'int' [-Wint-conversion]
  return add(fn_x(add, add), fn_y(add, add));
                       ^~~
tmp.c:11:35: warning: incompatible pointer to integer conversion passing 'int (int, int)' to parameter of type 'int' [-Wint-conversion]
  return add(fn_x(add, add), fn_y(add, add));
                                  ^~~
tmp.c:11:40: warning: incompatible pointer to integer conversion passing 'int (int, int)' to parameter of type 'int' [-Wint-conversion]
  return add(fn_x(add, add), fn_y(add, add));
                                       ^~~
tmp.c:21:23: warning: incompatible pointer types passing 'int (int (*)(int, int))' to parameter of type 'int (*)(int, int)'
      [-Wincompatible-pointer-types]
  int x = case_2_fn_a(case_2_fn_b, case_2_fn_b);
                      ^~~~~~~~~~~
tmp.c:10:17: note: passing argument to parameter 'fn_x' here
case_2_fn_a(int fn_x(int, int), int fn_y(int, int)) {
                ^
tmp.c:21:36: warning: incompatible pointer types passing 'int (int (*)(int, int))' to parameter of type 'int (*)(int, int)'
      [-Wincompatible-pointer-types]
  int x = case_2_fn_a(case_2_fn_b, case_2_fn_b);
                                   ^~~~~~~~~~~
tmp.c:10:37: note: passing argument to parameter 'fn_y' here
case_2_fn_a(int fn_x(int, int), int fn_y(int, int)) {
                                    ^
6 warnings generated.
Segmentation fault: 11
Run Code Online (Sandbox Code Playgroud)

本质上,我想将一系列函数传递给函数“ A”,然后让函数“ A”接受这些函数(让我们将它们称为函数“ B”,“ C”和“ D”),然后用几个函数来调用它们作为参数。然后,函数“ B”,“ C”和“ D”采用其函数参数,并将简单的值(例如整数或字符)传递给它们。

dbu*_*ush 5

首先,在将函数作为参数传递时,通常需要使用函数指针。因此,代替此作为参数:

int fn_x(int, int)
Run Code Online (Sandbox Code Playgroud)

您将使用此:

int (*fn_x)(int, int)
Run Code Online (Sandbox Code Playgroud)

现在针对主要问题:函数(和函数指针)作为参数和返回值可能具有令人困惑的语法。为函数指针创建typedef可以大大简化这一过程。

因此,让我们进行以下类型定义:

typedef int (*addfunc)(int, int);
typedef int (*fnb)(addfunc);
typedef int (*fna)(fnb, fnb);
Run Code Online (Sandbox Code Playgroud)

现在,您有了:

int
case_2_fn_a(fnb fn_x, fnb fn_y) {
  return add(fn_x(add), fn_y(add));
}

int
case_2_fn_b(addfunc fn_x) {
  return fn_x(1, 2);
}
Run Code Online (Sandbox Code Playgroud)

如您所见,语法更加简洁。同样更明显的是,的正文case_2_fn_a在向fn_xfn_y传递两个参数而不是一个参数时出错。

如果您确实想在没有typedef的情况下执行此操作,case_2_fn_a则将如下所示:

int
case_2_fn_a(int (*fn_x)(int (*)(int,int)), int (*fn_y)(int (*)(int,int))) {

  return add(fn_x(add), fn_y(add));
}
Run Code Online (Sandbox Code Playgroud)