Usein esimerkiksi matemaattisissa tehtävissä tulee vastaan tilanne, missä jollekin funktiolle tehty aliohjelma kelpaisi tekemään saman homman myös jollekin toiselle funktiolle, mikäli funktio pystyttäisiin vaihtamaan. Tyypillisiä tällaisia esimerkkejä ovat numeerinen derivointi ja integrointi, nollakohdan hakeminen, kuvaajan piirtäminen jne.
Esimerkiksi funktion integrointi suorakaidesäännöllä voitaisiin hoitaa seuraavasti:
#include <stdlib.h> #include <stdio.h> #include <math.h> double integroi(double x1, double x2, int tiheys) { double x,dx,summa=0; dx = (x2- x1)/tiheys; for (x=x1+dx/2 ; x<x2; x+=dx) summa += sin(x)*dx; return summa; } int main(void) { printf("Integraali sin(x) väliltä [0,pi] on noin %7.5lf\n", integroi(0,M_PI,100)); return 0; }
Entäpä mikäli haluaisimme integroida vaikka e x. No vaihdetaan sin(x) tilalle exp(x)! Entäpä jos tarvitsemme samassa ohjelmassa sekä sin(x) että exp(x) integraalit? Kirjoitammeko integroi_sin ja integroi_exp. Ei kuulosta järkevältä!
Otamme käyttöön funktio- osoittimet. Määritellään aluksi funktio_tyyppi
typedef double (*funktio_tyyppi)(double x);
Sitten voimme esitellä tarpeellisen määrän vastaavaa tyyppiä olevia funktiota. Itse integrointi muutetaan käyttämään yhtä "ylimääräistä" parametriä; funktiota jota integroidaan:
double oma_funktio(double x) { return 2*x- 5; } double integroi(funktio_tyyppi f,double x1, double x2, int tiheys) { double x,dx,summa=0; dx = (x2- x1)/tiheys; for (x=x1+dx/2 ; x<x2; x+=dx) summa += f(x)*dx; return summa; }
Nyt voimme kutsua esimerkiksi:
double ifx; ... ifx = integroi(oma_funktio,0,5,100); ... ifx = integroi(sin,0,M_PI,1000); ... ifx = integroi(exp,0,1,500); ...
Huomautus! Hienot adaptiiviset integrointimenetelmät muuttavat itse välin tiheyttä funktion käyttäytymisen mukaan.