Le funzioni in C

Il seguente tutorial spiega le funzioni con il linguaggio di programmazione C.

+--------------------------------+
|                                |
| # SOMMARIO #                     |
|                             |
| c1 - Definizione         |
| c2 - Dichiarazione         |
| c3 - Funzioni vs. puntatori    |
| c4 - Passaggio di parametri    |
| c5 - Ringraziamenti            |
|                 |
+--------------------------------+

+---------------------------------------------------------------------------------------------+
| c1 # DEFINZIONE #                                          |
|                                                  |
| La definizione di una funzione basata sulla specifica iniziale della sintassi del           |
| linguaggio, si presenta nella seguente forma:                              |
|                                                  |
| 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:                                       |
| o     viene esguita l'istruzione return                                                     |
| o     l'ultima istruzione del corpo della funzione e' stata eseguita                        |
| Quando la funzione termina, il controllo torna al chiamante.                          |
|                                                  |
| 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) */                                           |
|                                                  |
+---------------------------------------------------------------------------------------------+


+---------------------------------------------------------------------------------------------+
|                                                                                             |
| c2 # DICHIARAZIONE #                                                                        |
|                                                                                             |
|                                                                                             |
| Nella versione originale del linguaggio la dichiarazione si presenta con la sintassi        |
| seguente:                                              |
| 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. |
|                                                                                             |
+---------------------------------------------------------------------------------------------+


+---------------------------------------------------------------------------------------------+
|                                                                                             |
|  c3 # FUNZIONI vs. PUNTATORI #                                                              |
|                                                                                             |
| Il linguaggio C consente di dichiarare e/o definire, oltre alle funzioni, anche i           |
| puntatori alle funzioni.                                      |
| Ad essi possono essere assegnati gli indirizzi di altre funzioni, poiche' il tipo della     |
| funzione abbia lo stesso tipo della funzione puntata, cioe' che il puntatore punti ad un    |
| tipo di funzione con gli stessi parametri formali (per numero, posizione e tipo)            |
| e abbia lo stesso tipo di risultato, rispetto alla funzione di cui si vuole assegnare       |
| l'indirizzo.Inoltre i puntatori a funzione possono essere dereferenziati allo scopo di      |
| eseguire il codice della funzione a cui puntano.                          |
|                                                  |
| 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 è  |
| possibile impiegare semplicemente il nome della funzione, senza far                   |
| uno dell'operando indirizzo.                                                                |
|                                                                                             |
+---------------------------------------------------------------------------------------------+

+---------------------------------------------------------------------------------------------+
|                                                                                             |
|  c4 # PASSAGGIO DI PARAMETRI #                                                              |
|                                                                                             |
|   Nel C il passaggio dei paramteri ad una funzione, avviene sempre per valore, per cui non  |
|   e' possibile che una funzione abbia degli effetti collaterali sui parametri passati.      |
|   Esempio: #include <stdio.h> #include <stdlib.h>                    |
|            void funz(int a); int main(int argc, char *argv) { int a=10;               |
|            printf("a = %d\n\n", a); /* stampa "a = 10" */ funz(a); printf("a = %d\n\n", a); |
|            /* stampa ancora "a = 10" */ return 0; } void funz(int a) { a/=2;                |
|            printf("a = %d\n\n", a); /* stampa "a = 5" */ }                       |
|                                                  |
| 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: ... int main(int argc, char *argv[]) { int a1, b1, c1; ...                         |
| inizializza(&a1, &b1, &c1); /* chiamata alla funzione */ ... }                  |
| void inizializza(int *a, int *b, int *c) { *a = 5; *b = 7; *c = 20; }                       |
|                                                                                             |
+---------------------------------------------------------------------------------------------+


+---------------------------------------------------------------------------------------------+
|                                                   |
| c5 # RINGRAZIAMENTI #                                                                       |
|                                                                                             |
|                                                                                             |
|  Ringraziamenti:  Mio Prof. di Matematica. :***                           |
|                   (Se non fosse per lui, oggi questo tutorial non sarebbe qui)              |                
|                   zbs e gli amici di #el8                                                   |
|                   Rhapsody  ed il Team di Sideralis                           |
|                                                      |
|  [ skorpion@IRCnet: #giardini - #el8 - #sideralis - #linux-cafe - #odio - #void ]           |
|                                                  |
|  Commento: Non sono un granchè come programmatore in C, anche io sto imparando pian piano.  |
|                                                                                             |
|                                                         |
|                                                                                             |
|  Per suggerimenti o delucidazioni <[email protected]> ciao! ;)                     |
|                                                                                             |
|                                                      |
+---------------------------------------------------------------------------------------------+

Privacy Policy