______________________
/ void moo(){          \
|    printf("Moo!\n"); |
|    return;           |
\ }                    /
 ----------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

L’uso delle funzioni in C è una prassi necessaria per ottenere del codice di buona qualità, ed essere in grado di distinguere le funzionalità a cui far corrispondere una funzione, ovvero la corretta grana in cui particellare il codice consente una migliore pianificazione e uno sviluppo più rapido.

Le funzioni sono parti di codice ricorrente che, scritto una volta sola viene richiamato più volte. In molti linguaggi sussiste la distinzione tra funzione e procedura: la prima restituisce un valore, la seconda invece no. In C non esiste una distinzione sintattica tra i due casi ma solo logica. Anche se potrebbe sembrare un modo improprio di definire questo termine, indistintamente di funzioni quando queste:

  • non ricevono parametri e non restituiscono valori
  • non ricevono parametri ma restituiscono un valore
  • ricevono parametri ma non restituiscono valori
  • ricevono parametri e restituiscono un valore

La definizione di una funzione segue la seguente sintassi:

<tipo dato ritornato> <nome funzione> ([<tipo dato parametro> <parametro>[,<tipo dato parametro> <nome parametro>[, ...]]])

La seguente funzione non ritorna nessun valore, per tale motivo la funzione è dichiarata di tipo void. Tra le parentesi tonde che seguono il nome (che sono obbligatorie) non è presente alcun parametro: la funzione quindi non riceve nessun parametro dall’esterno né restituisce alcun valore. Ad ogni sua chiamata si limita a stampare una sequenza fissa di valori (in particolare evidenzia la corrispondenza tra codici ascii e i caratteri che rappresentano).

void AsciiTable()
{
   unsigned char i,j;
   for(i=4;i<16;i++){
      for(j=0;j<8;j++){
	 printf("%3d=%1c ", j+8*i, j+8*i);
      }
      printf("\n");
   }
   return;
}

L’ultima sua istruzione è un return, che non presenta parametri: alla funzione chiamante non verrà ritornato alcun valore; tra l’altro in questo caso il comando return non è obbligatorio e la funzione si comporta come ciò che in altri linguaggi è chiamata subroutine (che non esiste in C).

La seguente funzione invece riceve un parametro, una stringa da stampare, ma non restituisce alcun valore, pertanto è anch’essa definita void e termina con un return senza parametro.

void Avviso(char *messaggio)
{
	printf("Avviso: %s\n",messaggio);
	return;
}

È possibile passare alla funzione più di un parametro, separando i parametri con una virgola:

void Avvisi(char *messaggio, int n)
{
	for(int i=0; i<n; i++)
	{
		printf("Avviso: %s\n",messaggio);
	}
	return;
}

Una funzione definita void può comunque essere usata per scambiare valori tra funzione e chiamante, passando alla funzione non il valore della variabile bensì l’indirizzo, semplicemente definendo il parametro come puntatore (interponendo il simbolo *) nella definizione della funzione, mentre nella chiamata è necessario far precedere il simbolo & al nome della variabile, in questo modo è possibile modificare il contenuto dell’area di memoria puntata dal puntatore e ciò non contraddice il fatto che alle funzioni il passaggio dei parametri avviene solo per valore.

void Raddoppia(int *n)
{
	(*n)*=2;
	return;
}

int main()
{
	int n=5;
	printf("%d --> ",n);
	Raddoppia(&n);
	printf("%d\n",n);
	return 0;
}

Una funzione senza parametri e che ritorna un valore è definita come nell’esempio:

float Epsilon()
{
	float a,epsilon,e=1;
	do
	{
		epsilon=e;
		e/=2;
		a=1+e;
	}while(a!=1);
	return epsilon;
}

Nella prima riga viene indicato il tipo del valore ritornato dalla funzione, può un tipo standard[*], definito dallo sviluppatore e una struttura[*]. La funzione termina con l’istruzione return il cui parametro è dello stesso tipo con cui è definita la funzione.

Di seguito un esempio della sintassi da usare per invocare la funzione: in questo modo, al termine dell’esecuzione della funzione Epsilon la variabile eps sarà valorizzata con il valore di ritorno della funzione.

int main()
{
	float eps;
	eps = Epsilon();
	printf("%.16f\n",eps);
	return 0;
}

È possibile infine passare ad una funzione una o più valori e fare in modo che venga restituito un valore di ritorno:

int Doppio(int n)
{
	return 2*n;
}

int main()
{
	int n=5;
	int n2;
	n2=Doppio(n);
	printf("%d %d\n",n,n2);
	return 0;
}