Logo Background RSS

Pubblicita'

Puntatore a funzioni in C

  • Scritto da spriksprik 2 Comments2 commenti Comments
    Ultimo aggiornamento: 18 novembre, 2009

    imgprog

    Come una normalissima variabile, anche una funzione può essere rappresentata tramite il suo indirizzo di memoria.
    L’uso dei puntatori a funzioni è utile quando il nome della funzione è conosciuto solo al momento dell’esecuzione del programma: per esempio in base ad una scelta.
    La dichiarazione è simile a quella di una funzione normale, con la differenza che il nome della funzione è sostituito dal nome del puntatore preceduto dall’operatore unario di indirezione * :

    [[tipo]] (*Identificatore)( [[tipo [[parametro1]], tipo [[parametro2]], ... ]] );

    Per esempio, definendo una funzione Area:

    double Area(double b, double h)
    {
    return b*h;
    }

    la dichiarazione di un suo puntatore può essere la seguente:

    double (*Funzione) (double, double);

    e Funzione può essere inizializzata e richiamata come segue:

    Funzione = Area;
    valore = (*Funzione)(5.0, 3.1);

    Ovviamente, una cosa del genere non serve a molto, ma è utile quando ci sono più funzioni che è possibile raggruppare in un unico puntatore a funzioni, ecco un esempio completo:

    #include <stdio.h>
    #include <math.h>
    int main()
    {
    double (*Funzione[])(double) = {sin, cos, tan};/* Punto 1 */
    int scelta;
    double val;
    printf("Seleziona: ");
    printf("\n 1) seno");
    printf("\n 2) coseno");
    printf("\n 3) tangente");
    printf("\n 0) esci");
    do
    {
    printf("\n\nScegli: ");
    scanf("%d", &scelta);
    }while(scelta < 0 || scelta > 3);
    if(scelta > 0)
    {
    printf("\nInserisci valore: ");
    scanf("%lf", &val);
    printf("\nRisultato: %lf \n", (*Funzione[scelta-1])(val));/* Punto 2 */
    }
    }

    Nel punto 1 viene creato il puntatore ad un vettore di funzioni, in questo caso: seno, coseno e tangente.
    Nel punto 2 viene richiamata la funzione scelta, sottraendo 1 perchè, come ben dovremmo sapere tutti, in C l’indice dei vettori parte da 0, e nel menu dell’esempio si partiva da 1.

    Un puntatore a funzioni di questo tipo è utile quando ci sono molte funzioni, perchè fa risparmiare codice ottenendone uno più compatto e performante.

Pubblicita'

  1. #1 avatar JackTheVendicator
    18 novembre, 2009 2009-11-18T15:10:41+01:00200911Etc/GMT-1 20:44

    Piccolo esercizio di stile… copia il codice di una funzione in un vettore di unsigned char, gli punta sopra un puntatore a funzione ed esegue il codice copiato. Lo stesso “trucco” puo’ essere usato per inserire qualsiasi pezzo di codice binario dentro un sorgente…

    #include

    void test() {
    printf(“Prova\n”);
    }

    int main() {
    unsigned char *puntatore = test;

    unsigned char code_array[2048]; // Giusto per starci larghi

    int i;
    for(i=0; i < 2048; i++) {
    code_array[i] = *puntatore;
    puntatore++;
    }

    void (*puntatore2) () = code_array;
    (*puntatore2) ();

    system("PAUSE");
    }

    RispondiRispondi
  2. #2 avatar JackTheVendicator
    18 novembre, 2009 2009-11-18T15:10:41+01:00200911Etc/GMT-1 20:45

    Uff e’ saltato l’include… vabbe’… e’ a stdio.h comunque :-)

    RispondiRispondi
Inserisci un commento

:D :-) :( :o 8O :? 8) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: :1up: :alert: :beer: :borg: :coffee: :cuckoo: :cuss: :finger: :goombah: :megaman: :pity: :noshake: :oogle: :pacman: :pill: :poison: :poop: :rant: :satansmoking: :shake: :shiftyeyes: :shroom: :sick: :smirk: :stfu: :thumbdown: :thumbup: :turtle: :what: :whatever:
Notify me of follow-up comments via email.