编写一个函数,该函数将指向任何函数的指针作为参数

Write a function that takes as parameter a pointer to any of the functions

我正在为 C 中的指针苦苦挣扎。我必须编写一个程序,使用函数和指针对一个数 (sqrt、sin、exp) 进行 3 次运算。我已经做到了,但是我有一个问题编写一个函数,该函数将指向上述任何函数的指针+浮点数作为参数,返回相应计算的结果。 在主要功能中,我附加了没有此功能的工作代码。我不知道如何编写这个函数,我在这段代码中写了我的尝试。在这里附上我写的代码:

#include <stdio.h>
#include <math.h>

double square(double *);
double sinus(double *);
double exponential(double *);
void count(*square, double result);

double number, square_result, sinus_result, exponential_result;

int main()
{

    printf("Give number: ");
    scanf("%lf", &number);

    square_result = square(&number);
    sinus_result = sinus(&number);
    exponential_result = exponential(&number);

    printf("%lf\n", square_result);
    printf("%lf\n", sinus_result);
    printf("%lf", exponential_result); 

}

double square(double *x)
{
    double square_result;
    square_result = sqrt(*x);

    return square_result;
}

double sinus(double *x)
{
    double sinus_result;
    sinus_result = sin(*x);

    return sinus_result;
}

double exponential(double *x)
{
    double exponential_result;
    exponential_result = exp(*x);

    return exponential_result;
}

void count(*square, double result)
{
    result = square(&number);
}

对于初学者来说,将函数参数声明为指针类型没有任何意义 double *

double square(double *);
double sinus(double *);
double exponential(double *);

因为 double 类型的按引用传递的对象在函数内未更改。

像这样声明函数

double square(double );
double sinus(double );
double exponential(double );

他们将被称为

square_result = square( number);
sinus_result = sinus( number);
exponential_result = exponential(number);

所有这些函数的类型都是

double( double)

或者指向此类函数的指针类型类似于

double ( * )( double )

因此您可以声明所需的函数,例如

double f( double calc( double ), double value );

或等效

double f( double ( * calc )( double ), double value );

您可以使用自己的名称代替 f 和 calc。

并且函数可以被调用,例如

double result = f(  square, number );

你可以在函数中写

double f( double ( * calc )( double ), double value )
{
    return calc( value );
}

您可以声明一个指向函数的指针数组,例如

double ( *fp[] )( double ) = { square, sinus, exponential };
size_t N = sizeof( fp ) / sizeof( *fp );

并循环调用函数

for ( size_t i = 0; i < N; i++ _
{
    double result = f(  fp[i], number );
    //...
}

做出此声明

double ( *fp[] )( double ) = { square, sinus, exponential };

更简单的你可以引入一个typedef名称。例如

typedef double Func( double );

在这种情况下,数组声明看起来像

Func * fp[] = { square, sinus, exponential };

参考您的代码,使用 EITHER (1) 指针或 (2) return 值。

(1) 表示使用原始变量(原始地址),可以在子程序中更改。那么什么都不需要 returned.

(2) 给子程序提供一个变量的值,子程序将return结果。那么子程序的输入参数就不需要是指针了。

则(1)为(注意输入值被结果值代替)

void square_root(double *x)
{
    *x = sqrt(*x);
}

或 (1) 如果您不希望输入被结果替换

void square_root(double a, double *x)
{
    *x = sqrt(a);
}

或 (2) 是

double square_root(double a)
{ 
   double r;       
   r = sqrt(a);
   return r;
}

或 (2) 简而言之就是

double square_root(double a)
{ 
   return sqrt(a);
}

评论:通常,在这里我会选择第一个 (2) 版本。否则,如果您想使用指针,例如因为无论如何您都想从子例程中获取多个值,请选择 (1) 的第二个版本。

评论 2:指针可能非常有用。有时指针是(几乎)唯一的解决方案。您需要熟悉使用指针。如果不是,你宁愿引入潜在的风险,如果事情不太对劲。你需要了解为什么会这样。

评论 3:关于指向函数的指针。我建议,首先了解数据指针的概念。现在跳过指向函数的指针,除非你在学校需要它。那么以下可能是一个很好的参考: How do function pointers in C work?

我创建了一个函数 call_func 以函数指针作为参数和 double* 如下所示:

//arguments are a pointer to any functions taking argument double* and a double* number
double call_func(double (*MyFunction)(double* arg), double* number)
{
    return (MyFunction)(number);
}

// 一个小小的编辑,恕我直言,您不需要通过指针 number 传递

应该这样称呼:

    square_result = call_func(square, number);
    sinus_result = call_func(sinus, number);
    exponential_result = call_func(exponential,number);

在这里,集成在您的代码中:


// here is my function that takes a function pointer as an argument
double call_func(double (*MyFunction)(double* arg), double number);


int main()
{

    printf("Give number: ");
    scanf("%lf", &number);

    square_result = square(&number);
    sinus_result = sinus(&number);
    exponential_result = exponential(&number);

    printf("%lf\n", square_result);
    printf("%lf\n", sinus_result);
    printf("%lf", exponential_result);
    // call of my general function

    printf("\n********************************\n");
    printf("\n\nUSAGE OF FUNCTION POINTER \n");

    double square_result2 = 0.0;
    double sinus_result2 = 0.0;
    double exponential_result2 =0.0;

    square_result2 = call_func(square, &number);
    sinus_result2 = call_func(sinus, &number);
    exponential_result2 = call_func(exponential, &number);

    printf("%lf\n", square_result2);
    printf("%lf\n", sinus_result2);
    printf("%lf", exponential_result2);

}


//arguments are a pointer to any functions taking argument double and a double number
double call_func(double (*MyFunction)(double* arg), double* number)
{
    return (MyFunction)(number);
}