为什么将函数作为函数的参数传递?

时间:2019-07-10 17:27:25

标签: c windows dev-c++

我有一个小问题。 我正在用devc ++学习C(作为开始),我已经看过可以传递函数的参数函数,这没关系,但是为什么呢? 例如,您可以写为参数:

void myfunc(void(*func)(int)){}

但是如果您使用自己的名字和参数调用简单函数会更好吗?

例如:

void myfunction (){name of func to call(myargs);  }

有区别吗? 似乎是同一回事,但是代码更简单,更短

编辑:

我只想知道

void map (int (*fun) (int),int x[ ], int l) {
    for(i = 0; i < l; i++)
    x[i] = fun(x[i]);
}

为什么用它代替:

void map (int x[ ], int l) {
    for(i = 0; i < l; i++)
    x[i] = nameoffunction(yourargument);
}

3 个答案:

答案 0 :(得分:1)

如果希望函数根据用户的需要执行不同的操作,则可以使用函数指针作为参数。

这是一个简单的例子:

#include <stdio.h>

int add(int x, int y)
{
    return x + y;
}

int subtract(int x, int y)
{
    return x - y;
}

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

int divide(int x, int y)
{
    return x / y;
}

int operation(int x, int y, int (*func)(int, int))
{
    printf("  x=%d, y=%d\n", x, y);
    return func(x,y);
}

int main()
{
    int x = 8, y = 4;

    printf("x+y=%d\n", operation(x,y,add));
    printf("x-y=%d\n", operation(x,y,subtract));
    printf("x*y=%d\n", operation(x,y,multiply));
    printf("x/y=%d\n", operation(x,y,divide));
    return 0;
 }

答案 1 :(得分:1)

一个很好的例子是经典的排序功能qsort。这是一个库函数,这意味着您只能访问它的原型。为了使qsort通用,您必须编写自己的比较函数。对于常规整数,典型的实现如下所示:

int cmpfunc (const void * a, const void * b)
{
   return ( *(int*)a - *(int*)b ); 
}

然后,如果您有整数arr的数组,则可以用qsort(arr, sizeof(arr), cmpfunc)对其进行排序

您可能会问为什么qsort函数中没有内置此功能?毕竟,使它适用于浮点数和整数很容易。是的,但是想像一下,如果您有一系列如下所示的结构:

struct {
    char *firstname;
    char *lastname;
    int age;
} persons[10];

您如何排序?好吧,这并不明显。您可能要全部三个。在这种情况下,编写三个不同的比较函数。

答案 2 :(得分:0)

我只想知道
void map (int (*fun) (int),int x[ ], int l) {
    for(i = 0; i < l; i++)
    x[i] = fun(x[i]);
}
为什么你用这个代替:
void map (int x[ ], int l) {
    for(i = 0; i < l; i++)
    x[i] = nameoffunction(yourargument);
}

让我们回答一个问题-如果您要执行多种类型的映射该怎么办?如果要同时映射 x 2 √x,该怎么办?

您当然可以做类似的事情

void map( int x[], int l, int type )
{
  for ( int i = 0; i < l; i++ )
  {
    if ( type == MAP_SQUARED )
      x[i] = int_square( x );
    else if ( type == MAP_ROOT )
      x[i] = int_root( x );
    ...
  }
}

可行,但难以阅读且难以维护-每次要执行新映射时,都必须向map函数添加新的大小写。

比较

void map( int x[], int l, int (*fun)(int) )
{
  for ( int i = 0; i < l; i++ )
    x[i] = fun( x[i] );
}
...
map( x, l, int_square );
map( y, l, int_root );

您无需破解map函数即可获取不同的映射-您只需传递对单个元素进行操作的函数即可。如果要执行新的映射,则只需编写一个新函数-根本不必编辑map函数。

C标准库在多个地方使用这种委托形式,包括qsort函数(允许您以任何顺序对任何类型的数组进行排序)和signal函数(允许您进行更改)程序如何动态响应中断)。