// funkce, se kterými budeme pracovat, musí mít stejný prototyp z hlediska typů
double Secti(double a, double b)
{
return(a + b);
}


// další - alternativní funkce se stejným prototypem
double Odecti (double a, double b)
{
return(a – b);
}


// ukazatel na funkci je možné též vyřešit pomocí typedef jako nový typ. Takto definujeme typ ukazatel na funkci,
// která má dva parametry typu double a vrací double
typedef double (*UKFUN)(double,double);


// totéž jako před chvílí pomocí typedef typu

double FunkceT (double a, double b, UKFUN pf)
{
double ret;

ret = (*pf)(a,b);

return ret;
}


// způsob základního předání ukazatele na funkci
double Funkce (double a, double b, double (*pf)(double,double))
{
double ret;
// dereference (=zavolání) funkce předané ukazatelem
ret = (*pf)(a,b);
// výsledek je vyčíslen na základě předané funkce výhodou je to, že tato funkce je vybrána až za chodu
// programu na základě vnějších událostí
return ret;
}


// ukázka jak použít ukazatel na funkci ve struktuře
struct Vypocet
{
double c;
double d;
double (*pf)(double,double); // ukazatel na funkci jako parametr struktury
};


// předáváno by mělo být spíše přes ukazatel, či referenci
double FunkceS(struct Vypocet par)
{
return (*(par.pf))(par.c,par.d);
}



int main(int argc, char* argv[])
{
double p1 = 10, p2 = 33, p3;
// název funkce je vlastně ukazatel (vstupní bod funkce) ukazatel na funkci lze n apříklad vytisknout
printf ("Secti: %p\nOdecti: %p\n", Secti, Odecti);

double (*pf)(double,double);
pf = Secti; // s ukazatel na funkci (jeho hodnotou) můžem pracovat jako s jinými proměnnými (např. je můžeme přiřadit)
printf ("Secti: %p\n", pf); //printf ("Secti: %p\n", *pf);

pf = Odecti;
printf ("Odecti: %p\n", pf); // printf ("Odecti: %p\n", *pf);

// přidáme-li k ukazateli na funkci závorky pak ji zavoláme
p3 = Secti(p1,p2);
p3 = Odecti(p1,p2);

p3= (*pf)(p1,p2);

p3 = Funkce(p1,p2,Secti);
p3 = Funkce(p1,p2,Odecti);

struct Vypocet sv;
sv.c = p1;
sv.d = p2;
sv.pf = Secti;
p3 = FunkceS(sv);
sv.pf = Odecti;
p3 = FunkceS(sv);
return 0;
}