Visita Orebla.it su Facebook Segui Orebla.it su Twitter Vedi i video su YouTube di Orebla.it Unisciti alle cerchie di Orebla.it
DOVE TI TROVI: \\ Home Page\c\Guida al C : Funzioni delle procedure

Guida al C/C++

autore: BlackLight
xx/xx/xx

Funzioni e procedure:

Eccoci dunque ad uno dei momenti cruciali del nostro tutorial: l'uso delle funzioni e delle procedure.
Ogni linguaggio di programmazione ad alto livello mette a disposizione del programmatore questi strumenti, ed il C non è da meno!
Abbiamo già incontrato nel corso di tutorial un esempio di funzione: il main(). Il main() altro non è che una funzione speciale che viene eseguita all'inizio del programma, ma ovviamente noi possiamo definire anche altre funzioni (avevo già accennato che tutto ciò che si fa in C si fa tramite le funzioni. Anche la printf() che abbiamo usato nei paragrafi precedenti non è altro che una funzione definita in stdio.h).

Per capire meglio come lavorano le funzioni in C, ci aiuteremo con la definizione matematica di funzione.
Sappiamo che una funzione matematica è scritta in genere nella forma y=f(x), ossia ad ogni valore della variabile indipendente x corrisponde uno ed un solo valore della variabile dipendente y. Prendiamo ad esempio la funzione f(x)=x+2: ad ogni valore della x corrisponde uno ed un solo valore della funzione f(x), se x è 0, f(x) è 2, se x è 1, f(x) è 3, e così via.

Però è possibile che in una funzione ci sia più di una variabile indipendente: ad esempio, f(x,y)=x+y.

Le "variabili indipendenti" delle funzioni nelle funzioni C sono i parametri, ossia i valori che si danno in input alla funzione (anche se è possibile creare funzioni senza alcun parametro), mentre il "risultato" della funzione (la "variabile dipendente") si ottiene usando la keyword return che abbiamo già incontrato.
Ecco la struttura di una funzione in C:

tipo_ritornato nome_funzione(parametro1,parametro2...parametron) {
codice
codice
......
}


Ecco un piccolo esempio:

int square(int x) {
return x*x;
}


Questa funzione calcola il quadrato di un numero intero x. La variabile int x è il parametro che passo alla funzione. Ho stabilito all'inizio, dichiarando la funzione come int, che il valore ritornato dalla funzione (la "variabile dipendente") deve essere di tipo int. Attraverso la direttiva return stabilisco quale valore deve ritornare la funzione (in questo caso il quadrato del numero x, ossia x*x). In matematica, una funzione del genere la potrei scrivere come f(x)=x²...

Questa funzione la posso richiamare all'interno del main() o di qualsiasi altra funzione del programma. Esempio:

int y; // Dichiaro una variabile int
y = square(2); // Passo alla funzione square il valore 2,
// in modo che calcoli il quadrato di 2
printf ("Quadrato di 2: %d\n",y);


Ovviamente, posso dichiarare un'infinità di funzioni in questo modo. Ecco ad esempio una funzione che calcola la somma di due numeri:

int somma(int a, int b) {
return a+b;
} Invocazione:
int c;
c = somma(2,3); // c vale 5


La maggior parte delle funzioni matematiche, in ogni modo, sono dichiarate nel file math.h (ci sono ad esempio funzioni per calcolare il seno, il coseno o la tangente di un numero reale, il logaritmo, la radice quadrata, la potenza n-esima...), quindi se vi interessa fare un programma di impostazione matematica date un'occhiata a questo file per capire quale funzione usare.
Ovviamente, è anche possibile creare funzioni senza alcun parametro in input. Esempio (stupido):

int ritorna_zero() {
return 0;
}


Vediamo ora come inserire una funzione nel nostro programma. Le funzioni in C possono andare in qualsiasi parte del codice, ma l'ANSI-C, per evitare confusione, ha imposto che all'inizio del programma ci vadano i prototipi delle funzioni usate dal programma stesso. Un prototipo non è altro che la funzione vera e propria (tipo ritornato, nome e parametri) senza però la sua implementazione, ossia senza il codice fra le parentesi graffe {}. Esempio:

int square(int x);

Ecco qui un programmino d'esempio che calcola il quadrato di un numero intero stabilito attraverso la funzione square():

/* square.c */
#include < stdio.h >
int square(int x); // Prototipo della funzione
int main() {
int y; // Variabile intera
y = square(3); // Ora y vale 9
printf ("Quadrato di 3: %d\n",y);
// Più brevemente, potremo scrivere:
// printf ("Quadrato di 3: %d\n",square(3));
// senza neanche "scomodare" la variabile y
return 0;
}
int square(int x) { // Implementazione della funzione square()
return x*x;
}

Nei programmi di grandi dimensioni, in genere si mette il prototipo della funzione in un file header (con estensione .h), l'implementazione in un file .c e poi il programma vero e proprio nel file main.c. Esempio:

/* Questo è il file square.h */
int square(int x);

/* Questo è il file square.c */
int square(int x) {
return x*x;
}

/* Questo è il file main.c */
#include < stdio.h >
#include "square.h"
// Ovviamente includo il file square.h

int main() {
printf ("Quadrato di 4: %d\n",square(4));
return 0;
}

Ovviamente, quando vado a compilare questo programma devo fare una cosa del genere:

gcc -o square main.c square.c

Ma per i nostri piccoli programmini non è il caso di fare una cosa del genere! Ci va tutto in un file.


Un discorso simile a quello delle funzioni vale anche per le procedure; le procedure non solo altro che funzioni "speciali", funzioni che non hanno un valore ritornato: eseguono un pezzo di codice ed esce. Per concludere una procedura non è necessario il return (in quanto non ritorna alcun valore): al massimo ci possiamo mettere un return;. Per dichiarare una procedura userò la keyword void:

void hello() {
printf ("Hello world!\n");
return; // Questa riga è opzionale
}

Quando voglio chiamare questa procedura all'interno di una qualsiasi funzione, basterà fare così:

hello();

Esempio:

#include < stdio.h >

void hello(); // Prototipo della procedura

int main() {
hello(); // Stampo la scritta "Hello world!"
// attraverso la procedura hello()
return 0;
}

void hello() { // Implementazione della procedura
printf ("Hello world!\n");
}

Ovviamente anche alle procedure posso passare qualche parametro. Esempio:

void stampa_var(int x) {
printf ("Valore della variabile passata: %d\n",x);
}

Invocazione:

stampa_var(3); // L'output è: "Valore della variabile passata: 3

Nota tecnica: attenzione a non fare cose del genere!

int square(int x);
double square(double x);

Quando vado a chiamare la funzione:

square(3);


il compilatore non sa che funzione chiamare e va in crash! Proprio per evitare ambiguità del genere, la maggior parte dei compilatori danno un errore (o almeno un warning) quando nel programma compaiono scritture del genere (tuttavia, nel C++ cose del genere sono possibili, con l'overloading delle funzioni, ossia con la dichiarazione di più funzioni con lo stesso nome MA con la lista dei parametri differente. In ogni caso, una scrittura come quella di sopra darà problemi anche in C++, in quanto entrambe le funzioni hanno un solo parametro e il compilatore, nel momento dell'invocazione, non sa quale funzione chiamare).





Articoli utili:
Jailbreak iOS 10: tweaks compatibili

Recensione iPhone 6

IPhone 7 uscito, novita, prezzi