FUNZIONI COME PARAMETRI DI FUNZIONE

In C, dato che le funzioni (procedure) sono solo parametrizzate su valori, è possibile avere altre funzioni come parametri solamente considerando dei puntatori ad esse (come si è già visto per avere delle variabili come parametri).

Notare che i tipi puntatori a funzioni sono tipi puntatori come gli altri che quindi si possono usare anche per dichiarare variabili e per costruire tipi strutturati (es. un array di puntatori a funzioni).

Un parametro formale di tipo funzione si dichiara nel seguente modo
TYPE(*IDENTIFIER) (FORMAL PARAMETERS) dove

TYPE
è il tipo dei valori ritornati dalla funzione
IDENTIFIER
è il parametro formale
FORMAL PARAMETERS
sono i parametri della funzione parametro, basta indicare i loro tipi, i loro nomi sono omessi.
Nel corpo della funzione il parametro formale IDENTIFIER sarà utilizzato attraverso l'operazione contenuto (*IDENTIFIER) per costruire delle chiamate.

Il corrispondente parametro attuale sarà il nome di una funzione dichiarata nel programma tale che il tipo dei valori ritornati e dei parametri è in accordo a quelli del parametro formale.

#include <stdio.h>
#define DIM 5
#define TRUE 1

void Map(int v[] /*valore*/, int len, int (*op)(int), 
         int res[]/*variabile*/ )
/* applica op, una funzione che preso un intero ritorna un intero,
   a tutti gli elementi di v e ritorna il nuovo array in res*/
{
   int i;
   for(i=0; i < len ; i++)
      res[i] = (*op)(v[i]);
}

int Apply(int v[]/*valore*/, int len, int (*op)(int,int), 
          int identity /*identita' di op*/)
/*ritorna v[0] op v[1] op ... op v[len-1],
  dove op e' una funzione che presi due interi ritorna un intero */
{  
   int i, res = identity;
   
   for(i=0; i < len ; i++)
      res = (*op)(v[i],res);
   return res;
}

int And(int x, int y){ return x && y; };

int All(int v[] /*valore*/, int len, int (*op)(int))
/*controlla se op vale su tutti gli elementi di v,
  dove op e' una funzione da interi in booleani (simulati da interi in C)*/
{
    int aux[DIM];
    
    Map(v,len,(*op),aux);
    return(Apply(aux,len,And,TRUE));
}

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

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

int Dec(int x){ return x-1; }

int Pos(int x){ return x > 0; }


main(){
    int vet[DIM] = { 1, 2, 3, 4, 5 };
    int w[DIM];
    int i;
    
    printf("La somma di tutti gli elementi di vet e\' %d\n",Apply(vet,DIM,Add,0));
    printf("Il prodotto di tutti gli elementi di vet e\' %d\n",Apply(vet,DIM,Prod,1));
    
    Map(vet,DIM,Dec,w);
    for(i=0;i<DIM;i++)
        printf("%d  ",w[i]);
    printf("\n");
    
    if(All(vet,DIM,Pos)) printf("in vet tutti positivi\n");
    if(!All(w,DIM,Pos)) printf("in w non tutti positivi\n");
}