tiporitornato nomefunzione(lista_parametri_formali) dichiarazione_parametri_formali { definizioni/dichiarazioni lista_statement }
Se il tiporitornato non viene specificato, per default viene assunto
di tipo int.
Se la funzione non ritorna alcun risultato. allora tiporitornato
deve essere specificato di tipo void.
Esempio di definizione:
int fattoriale(n) int n; { if (n > 1) return n*fattoriale(n-1); else return 1; }
La definizione della funzione effettuata in base alle specifiche
della versione ANSI del linguaggio C, assume la forma:
tiporitornato nomefunzione(dichiarazione_parametri_formali) { definizioni/dichiarazioni lista_statement }
Se la funzione non accetta parametri, la
dichiarazione_parametri_formali
deve essere specificata di tipo void.
Esempio:
int funzione_senza_parametri(void)
Esempio di definizione:
int fattoriale(int n) { if (n > 1) return n*fattoriale(n-1); else return 1; }
Indipendentemente dai 2 modi di definizione della funzione, essa ha termine al verificarsi di una delle condizioni:
![]() |
viene esguita l'istruzione return |
![]() |
l'ultima istruzione del corpo della funzione e' stata eseguita |
Una funzione puo' essere invocata tramite il codice:
nomefunzione(lista_parametri_attuali)
N. B. - Il C non specifica l'ordine di valutazione dei
parametri attuali, pertanto bisogna prestare attenzione affinche' gli
effetti collaterali non intervengano su variabili utilizzate anche
per altri parametri.
Esempio di chiamata ERRATA:
int j=0; ... funzione(j=5, j+1); /* ERRATA */ /* Puo' venire eseguita la valutazione di * j+1, prima dell'assegnamento j=5 !!! * (dipende dalla implementazione del * compilatore) */
tiporisultato nomefunzione();
mentre nella versione ANSI, appare il concetto di prototype della
funzione, attraverso il quale viene effettuato il controllo del
tipo dei parametri passati durante la chiamata della funzione.
Il controllo e' effettuato al tempo di compilazione e questo costituisce,
senza dubbio, un notevole vantaggio.
Il prototype presenta la sintassi seguente:
tiporisultato nomefunzione(dichiarazione_parametri_formali);
Qualora la funzione non accetti parametri, la dichiarazione_parametri_formali deve essere definita come void.
In entrambe le situazioni, la dichiarazione della funzione e' necessaria se viene invocata prima della sua definizione, oppure se e' definita in altro file e compilata separatamente.
Inoltre il C considera il nome della funzione come il puntatore al suo
codice, per cui non occorre applicare gli operatori indirizzo & e
indirezione *, sebbene il linguaggio ne permetta anche il loro impiego.
Esempio:
int funz(int a); /* prototype funzione */ int (*pf)(int); /* pf e' puntatore ad una funzione, avente un * parametro di tipo int e ritorna un int, cioe' * int f(int) */ ... pf = &funz; /* oppure pf = funz; */ (*pf)(5); /* oppure pf(5); */
Facendo uso di puntatori, anche le funzioni possono far parte dei
parametri di una funzione e possono essere restituite come risultato
di una funzione.
Data l'equivalenza tra il puntatore della funzione ed il suo nome, anche
per questi casi e' possibile impiegare semplicemente il nome della
funzione, senza far uno dell'operando indirizzo.
Qualora, invece, sia proprio necessario che la chiamata di una funzione
produca degli effetti collaterali, allora diventa indispensabile passare
alla funzione gli indirizzi di memoria di dove si devono ottenere gli
effetti collaterali. In altri termini vengono passati alla funzione gli
indirizzi degli argomenti per i quali siano richiesti gli effetti
collaterali.
In questo modo, i puntatori sono ancora passati per valore, e pertanto
non possono essere modificati dalla funzione, mentre puo' venire
modificato il contenuto a cui essi puntano.
Esempio: