Sei sulla pagina 1di 7

2

Indirizzo di una funzione


 Si può chiamare una funzione utilizzando
l’indirizzo di memoria dal quale inizia il codice
Puntatori a funzioni eseguibile della funzione stessa
 L’indirizzo di memoria di una funzione può
essere assegnato ad una variabile puntatore,
memorizzato in un vettore, passato a una
Ver. 2.4 funzione, restituito da una funzione

© 2010 - Claudio Fornaro - Corso di programmazione in C

3 4

Definizione di variabili Definizione di variabili


 tipo (*nome)(parametri );  double (*fp)();
definisce la variabile nome come puntatore a definisce fp come variabile puntatore a una
una funzione che restituisce un valore del tipo funzione che restituisce un double, nulla è
indicato e richiede i parametri indicati indicato per i suoi parametri, quindi non
 Le parentesi intorno al nome sono necessarie vengono controllati (un compilatore C++
altrimenti si ha: invece considera l’argomento come void)
tipo *nome(parametri );  double (*fp)(double, double);
e questa costituisce il prototipo di una definisce fp come variabile puntatore a una
funzione che restituisce un puntatore del tipo funzione che ha come parametri due double
indicato e richiede i parametri indicati e restituisce un double
5 6

Definizione di variabili Inizializzazione


 int (*fpv[3])(long);  Il nome di una funzione equivale al suo
definisce fpv come vettore di 3 elementi, indirizzo di memoria (come per i vettori)
ciascuno è un puntatore a una funzione che  Con le seguenti funzioni (prototipi):
ha come parametri un long e restituisce un double pow(double,double);
int double atan2(double,double);
 Le definizioni esterne inizializzano a NULL le int f1(long), f2(long);
variabili puntatori a funzioni si possono avere le seguenti inizializzazioni:
double (*fp)(double,double) = NULL;
double (*fp)(double,double) = pow;
int (*fpv[3])(long)={f1,f2}; /*+1NULL*/
int (*fpv[3])(long)={NULL};/*3 NULL*/

7 8

Utilizzo con typedef Assegnazione


 typedef può definire un tipo puntatore a  Il nome di una funzione equivale al suo
funzione con determinati parametri e valore indirizzo di memoria (come per i vettori)
restituito  L’operatore & è ininfluente se applicato al
 typedef double (*fpType)(double,double); nome di una funzione
dichiara fpType come tipo puntatore a
 Esempi (l’operatore & può essere omesso):
funzione con due argomenti double e che
restituisce un double fp = &atan2;
fp = atan2;
 fpType fp = pow;
fpType fpv[5] = {pow,NULL,atan2}; fpv[2] = &f1;
fpv[2] = f1;
Nota: fpv[3] e fpv[4] sono inizializzati a
NULL perché l’inizializzazione dei primi
elementi impone 0 (NULL) per i rimanenti
9 10

Confronto Chiamata della funzione


 È un normale confronto tra puntatori,  La funzione il cui puntatore è stato
permette ad esempio di determinare se il memorizzato nella variabile fp può essere
puntatore si riferisce ad una certa funzione o richiamata in due modi equivalenti:
no oppure se è NULL  (*fp)(argomenti)
 fp(argomenti)
if (fp == pow)
printf("fp punta a pow\n");  Il primo metodo rende più evidente che si
tratta di un puntatore a funzione e non del
nome di una funzione, il secondo è più
leggibile e comodo
x = (*fp)(2.23, 4.76);
x = fp(2.23, 4.76);
i = (*fpv[1])(22);
i = fpv[1](22);

11 12

Passaggio a funzione Passaggio a funzione


 Un puntatore a funzione può essere passato  Esempio
ad una funzione come argomento Si supponga di avere le due funzioni seguenti:
 Questo permette di passare ad una funzione  int piu(int a,int b) fa la somma di 2
[puntatori a] funzioni diverse per ottenere numeri interi
dalla stessa funzione comportamenti diversi  int meno(int a,int b) fa la differenza di 2
numeri interi
 Il parametro attuale deve essere il nome di
m = calc(12, 23, piu);
una funzione
calcola somma dei due valori
 Il parametro formale deve essere il prototipo
n = calc(12, 23, meno);
delle funzioni chiamabili (è lì che viene
calcola la differenza dei due valori
definito il nome del puntatore visto
dall’interno della funzione stessa)
13 14

Passaggio a funzione Valore restituito da funzione


int piu(int a,int b) {return a+b;}  Una funzione può restituire un puntatore a
int meno(int a,int b) {return a-b;} funzione (2 metodi)
int calc(int x,int y,int (*funz)(int,int))  Primo metodo
{ Si definisce con l’istruzione typedef il tipo
return (*funz)(x,y); il nome funz viene del puntatore-a-funzione restituito dalla
dichiarato qui…
} funzione chiamata:
main() …e usato qui typedef int (*TipoFunz)(int,int);
{ TipoFunz è un nuovo tipo: puntatore-a-
int m, n; funzione-che-ha-2-argomenti-int-e-
m = calc(12, 23, piu); restituisce-un-int
n = calc(12, 23, meno);
E lo si usa nel solito modo:
... TipoFunz operaz(int x);

15 16

Valore restituito da funzione Valore restituito da funzione


 typedef int (*TipoFunz)(int,int);  Secondo metodo (meno chiaro)
int piu(int a,int b) {return a+b;} Si scrive ogni cast esplicitamente
int meno(int a,int b) {return a-b;} int (* operaz(int f))(int,int)
TipoFunz operaz(int f)
{ {
static TipoFunz fpv[2]={piu,meno}; static int (* fpv[2])(int,int) =
return fpv[f]; {piu,meno};
} static per poter usare return fpv[f];
main() il puntatore dopo che la }
{ funzione è terminata  La funzione definita è operaz e f ne è l’argomento
int y;
TipoFunz op; /* var. puntatore */  la parte non sottolineata è il tipo della funzione
restituita da operaz (dove (int,int) sono i
op = operaz(1); /* scelta op. */ parametri della funzione restituita)
y = (*op)(12, 23);
 static è riferito a fpv
}
17 18

Valore restituito da funzione Cast


Secondo metodo (Continuazione)  Un cast di tipo puntatore-a-funzione
main() “fa credere” al compilatore che la funzione a
{ cui viene applicato abbia il tipo di quella del
int y; puntatore
int (*op)(int,int);/*puntatore */  Si ricorda che il tipo di una funzione è definito
op = operaz(1); /* scelta op. */ dal tipo e numero dei parametri e dal tipo del
y = (*op)(12, 23); valore restituito
}
 Il cast può essere premesso al nome di una
funzione o a un puntatore a funzione
 Attenzione che il cast di tipo puntatore-a-
funzione non applica anche il cast agli
argomenti e al valore restituito

19
Passaggio a funzione con cast 20

Cast qsort
 Il cast di puntatore-a-funzione può essere  La funzione qsort in <stdlib.h> ordina un
utilizzato per rendere una funzione vettore, deve essere chiamata indicando il
compatibile con quella richiesta come nome della funzione da usare per il confronto
argomento da un’altra funzione degli elementi, il suo prototipo è:
 E’ indispensabile che gli argomenti siano void qsort(
comunque compatibili (in generale sono void *base,  puntatore al vett da riordinare
puntatori) size_t n,  sua dim (numero di elementi)
size_t size,  dim di ogni elemento (in byte)
 Si veda l’esempio del qsort seguente int (*cmp)(const void*,const void*))
cmp è il puntatore alla funzione da utilizzare
per confrontare due elementi di quel vettore
Passaggio a funzione con cast 21
Passaggio a funzione con cast 22

qsort qsort su vettore di interi


 La funzione passata per cmp deve: #include <stdlib.h>
 avere come argomenti due puntatori agli elementi #include <stdio.h>
del vettore da confrontare (qsort passerà a cmp
gli indirizzi dei due elementi mediante &base[i]) int cfr(const int *a, const int *b)
 restituire un valore int: {
if (*a < *b) return -1;
 <0 se il 1o elemento è minore del 2o
else if (*a > *b) return +1;
 0 se sono uguali else return 0;
 >0 se il 1o è maggiore del 2o }
 La clausola const indica che gli oggetti da main()
confrontare non saranno modificati {
 Il tipo void* permette di passare puntatori di int vett[10] = {3,2,5,4,7,9,0,1,6,8};
qsort(vett, 10, sizeof(int),
qualsiasi tipo: sarà la funzione passata ad (int (*)(const void*,const void*))cfr );
utilizzarli ritrasformandoli al tipo corretto }

Passaggio a funzione con cast 23


Passaggio a funzione con cast 24

qsort su vettore di interi qsort su vettore di stringhe


 La funzione passata cfr ha prototipo non  Per ordinare con qsort un vettore di stringhe
identico a quello richiesto, ma compatibile (i char *vs[10] non si può utilizzare
puntatori sono sempre assegnabili gli uni agli direttamente strcmp
altri anche se di tipo diverso); quindi viene  Gli elementi che qsort() passerebbe alla
fatto un cast della funzione passata: funzione di confronto sarebbero &vs[i], cioè
(int (*)(const void*,const void*))cfr i puntatori (indirizzi) ai puntatori agli
 I valori che la funzione qsort passa elementi, mentre strcmp() richiede
automaticamente a cfr per essere confrontati puntatori a char
sono i vari &vett[i] che vengono usati
come puntatori a int (quali sono)
Passaggio a funzione con cast 25
Passaggio a funzione con cast 26

qsort su vettore di stringhe qsort su vettore di strutture


 Bisogna definire una funzione ausiliaria:  Per ordinare un vettore di struct bisogna
int cp(const void *p1,const void *p2) definire una funzione di confronto ausiliaria:
{ int structcmp(const void *p1,
return strcmp(*(char * const *)p1, const void *p2)
*(char * const *)p2); {
} const struct nome *sp1;
 Gli argomenti di cp sono generici puntatori const struct nome *sp2;
costanti a void (const void * ), il cast sp1=(const struct nome *)p1;
(char * const *) li riconverte nel loro vero sp2=(const struct nome *)p2;
tipo (puntatore a puntatore costante a char) e if (sp1->membro > sp2->membro)
la deferenziazione produce un puntatore return +1;
costante a char come la strcmp richiede else if (...

27

Esercizi
1. Scrivere un programma che riordini con
qsort un vettore di stringhe
2. Scrivere un programma che
1. definisca un vettore di 10 struct contenenti due
valori interi x e y
2. inizializzi il vettore
3. ordini il vettore con qsort in base alla somma dei
valori (se due somme sono uguali, il confronto è
tra i primi membri, es. {4,6}>{3,7})
4. cerchi un elemento, dati i due valori in input, con
la bsearch di <stdlib.h> e ne fornisca l’indice

Potrebbero piacerti anche

  • 25 AlberiBin
    25 AlberiBin
    Documento5 pagine
    25 AlberiBin
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 23 Liste
    23 Liste
    Documento10 pagine
    23 Liste
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 20 Complementi 2
    20 Complementi 2
    Documento6 pagine
    20 Complementi 2
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 22 VarArgs
    22 VarArgs
    Documento3 pagine
    22 VarArgs
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 24 Ricorsione
    24 Ricorsione
    Documento28 pagine
    24 Ricorsione
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 26 Adt
    26 Adt
    Documento8 pagine
    26 Adt
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 21 LongJmp
    21 LongJmp
    Documento3 pagine
    21 LongJmp
    Riccardo Ricci
    Nessuna valutazione finora
  • 18 DynAlloc
    18 DynAlloc
    Documento8 pagine
    18 DynAlloc
    Riccardo Ricci
    Nessuna valutazione finora
  • 15 Struct
    15 Struct
    Documento10 pagine
    15 Struct
    openid_9xLqqfRO
    Nessuna valutazione finora
  • Puntatori - PoliTo
    Puntatori - PoliTo
    Documento14 pagine
    Puntatori - PoliTo
    Flavia Isernia
    Nessuna valutazione finora
  • 17 Macro
    17 Macro
    Documento6 pagine
    17 Macro
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 14 Funzioni
    14 Funzioni
    Documento21 pagine
    14 Funzioni
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 16 FileRandom
    16 FileRandom
    Documento5 pagine
    16 FileRandom
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 11 File
    11 File
    Documento17 pagine
    11 File
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 05 Espressioni
    05 Espressioni
    Documento10 pagine
    05 Espressioni
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 12-Algoritmi Ordinamento
    12-Algoritmi Ordinamento
    Documento9 pagine
    12-Algoritmi Ordinamento
    Francesco Cds Caruso
    Nessuna valutazione finora
  • 09 Stringhe
    09 Stringhe
    Documento14 pagine
    09 Stringhe
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 08 VettMat
    08 VettMat
    Documento9 pagine
    08 VettMat
    Alessio Barile
    Nessuna valutazione finora
  • 02 LinguaggioC
    02 LinguaggioC
    Documento3 pagine
    02 LinguaggioC
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 10 Complementi 1
    10 Complementi 1
    Documento10 pagine
    10 Complementi 1
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 07 Cicli
    07 Cicli
    Documento12 pagine
    07 Cicli
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 04 IOnumeri
    04 IOnumeri
    Documento7 pagine
    04 IOnumeri
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 06 Selezione
    06 Selezione
    Documento9 pagine
    06 Selezione
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 03 Tipi
    03 Tipi
    Documento8 pagine
    03 Tipi
    openid_9xLqqfRO
    Nessuna valutazione finora
  • Seconda Prova - PNI (Matematica) 2009
    Seconda Prova - PNI (Matematica) 2009
    Documento2 pagine
    Seconda Prova - PNI (Matematica) 2009
    pacbard
    Nessuna valutazione finora
  • Olimpiadi Berlino
    Olimpiadi Berlino
    Documento3 pagine
    Olimpiadi Berlino
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 00 Programmazione
    00 Programmazione
    Documento6 pagine
    00 Programmazione
    Alessio Barile
    Nessuna valutazione finora
  • 01 PrimoEsper
    01 PrimoEsper
    Documento9 pagine
    01 PrimoEsper
    Riccardo Ricci
    Nessuna valutazione finora
  • Pendolo Molla e Onde
    Pendolo Molla e Onde
    Documento2 pagine
    Pendolo Molla e Onde
    openid_9xLqqfRO
    Nessuna valutazione finora