←to practical programming

Note "passing functions as paramters"

Pointer to function

A pointer to a function is an ordinary type in the C-language. It can be declared as, for example, the following,
double (*f)(double); /* f is a pointer to double function of double argument, like cos */
The variable f contains a pointer to a function that takes one double argument and returns a double result.

One can assign a value to this variable and then use it as a normal function, for example, after #include"math.h",

f=&sin;
printf( "%g\n", (*f)(0) );
Interestingly, in the C-language the following phenomena are observed:
  1. One can call both functions and function pointers,
    double x = sin(1.0);
    double y = (&sin)(1.0); /* apparently allowed */
    
  2. Ordinary functions are implicitly converted to function pointers (pointing to themselves);

Therefore, the following code is equally valid,

double (*f)(double);
f=sin;                   /* sin is implicitly converted to &sin */
printf( "%g\n", f(0) );  /* ok to call function pointer */

Functions as arguments

One can pass pointers to functions as arguments to other functions just like any other variables, for example,
#include"stdio.h"
#include"math.h"

void print_table( double (*f)(double), double a, double b, double dx ) {
	for(double x=a;x<=b;x+=dx)
        	printf("%10g %10g\n",x,f(x));
        }

int main(){
        print_table (&sin,0,M_PI,0.1);
        print_table ( cos,0,M_PI,0.1); // equally good
return 0;
}

Pointers to functions in arrays and structures

Pointers to functions, like other types of variables, can be elements of arrays,

#include"stdio.h"
#include"math.h"

int main(){
        double (*f[3])(double) = {sin,cos,tan};
	f[2]=exp;
        for(int i=0;i<3;i++)printf("%g\n",f[i](1));
return 0;
}
or members of structures,
#include"stdio.h"
#include"math.h"
struct funs {double (*fa) (double); double (*fb) (double);};
int main(){
        struct funs F = {.fa=sin,.fb=cos};
        printf("%g %g\n",F.fa(1),F.fb(1));
return 0;
}

Functions with parameters

There are no anonymous functions in the standard C language. All functions must be defined at compile-time. However one often needs to pass around functions with additional parameters. In this case one can do the following,
  1. (quick and dirty) Declare the parameters in the enclosing scope, for example,
    #include"stdio.h"
    #include"math.h"
    
    double k=1; // file scope
    double f(double x){return sin(k*x);} // k from file scope
    
    void print_table( double (*f)(double), double a, double b, double dx ) {
    	for(double x=a;x<=b;x+=dx)
            	printf("%10g %10g\n",x,f(x));
            }
    
    int main(){
    	k=1; // k from file scope affects f
    	print_table (f,0,M_PI,0.2);
    	k=2;
    	print_table (f,0,M_PI,0.2);
    return 0;
    }
    
  2. (the right thing) Keep the parameters in a structure, for example,
    #include"stdio.h"
    #include"math.h"
    
    typedef struct {double (*f)(double,void*); void* params;} Fun;
    double f(double x, void* params){
            double k=*(double*)params;
            return sin(k*x);
    }
    
    void print_table(Fun F, double a, double b, double dx ) {
            for(double x=a;x<=b;x+=dx)
                    printf("%10g %10g\n",x,F.f(x,F.params));
            }
    
    int main(){
            double k=1;
            Fun F = {.f=&f, .params=(void*)&k};
            k=1; print_table (F,0,M_PI,0.2);
            k=2; print_table (F,0,M_PI,0.2);
    return 0;
    }