C Why function pointer as parameter instead of jus

2020-04-14 07:01发布

I have been reading about having functions with functions as parameters, and particulary in C, they use function pointers. Let's suppose I want to implement the newton raphson method (in a simple way) for computing zeros in non linear equations.

double derivative(double f(double), double x)
{
    double h = 1e-9;
    return (f(x + h) - f(x)) / h;
}

double newton_raphson(double f(double), double x0, double tol)
{
    double xk, diff;

    do
    {
        xk = x0 - f(x0) / derivative(f, x0);
        diff = fabs(xk - x0);
        x0 = xk;
    } while (diff >= tol);
    return xk;
}

So, to compute an approximation for derivative I need a function that returns a double and takes a double as an argument. Same for computing a root of the function, given the other parameters. My question is, why is this different from declaring function parameters as function pointers? For instance declaring the input parameter f as a function pointer instead of just a function...

2条回答
forever°为你锁心
2楼-- · 2020-04-14 07:35

The parameter f is a pointer-to-function in both derivative and newton_raphson.

double derivative(double f(double), double x) { ... }

is exactly equivalent to

double derivative(double (*f)(double), double x) { ... }

Only, the former looks nicer - usually when you can omit parentheses, you should probably do so. After all both of them are equivalent to

double ((((derivative)))(double (((*(f))))(double ((trouble))), double ((x)))) { ... }

That I hope will only ever be used in IOCCC.


However, if you're declaring, defining a variable (not a function parameter), you need to use

double (*f)(double);

as

double f(double);

is just a function declaration.


6.7.6.3 Function declarators (including prototypes) of C11 draft n1570 says:

A declaration of a parameter as ‘‘function returning type ’’ shall be adjusted to ‘‘pointer to function returning type ’’, as in 6.3.2.1.

And 6.9.1 Function definitions further says that

[...] the type of each parameter is adjusted as described in 6.7.6.3 for a parameter type list; the resulting type shall be a complete object type.

additionally it has the following example:

EXAMPLE 2

To pass one function to another, one might say

int f(void);
/* ... */
g(f);

Then the definition of g might read

void g(int (*funcp)(void))
{
      /* ... *
      (*funcp)(); /* or funcp(); ... */
}

or, equivalently,

void g(int func(void))
{
      /* ... */
      func(); /* or (*func)(); ... */
}
查看更多
Emotional °昔
3楼-- · 2020-04-14 07:36

Like normal data pointers, a function pointer can be passed as an argument and can also be returned from a function. A function’s name holds the address of function.

My question is, why is this different from declaring function parameters as function pointers? For instance declaring the input parameter f as a function pointer instead of just a function...

The answer is that both forms will be treated as same by compiler. But for readibility of your code, go with the kind of declaration that your example code has, i.e.,

double derivative(double f(double), double x) { ... }

Even in C, the function definitions given below will be interpreted as same-

void foo(int a[]) // or int a[10]
{
     ...
}

void foo(int *a)
{
     ...
}
查看更多
登录 后发表回答