Oggi parleremo delle funzioni in C, uno strumento molto utile e potente che consente il riutilizzo di blocchi di istruzione.

Una funzione può essere vista come un sottoprogramma dove vengono aggregati gruppi di istruzioni.

Le funzioni in C sono utilizzate proprio per evitare di replicare porzioni di codice; infatti invocare un sottoprogramma vuol dire mandare in esecuzione la porzione di codice ad esso relativa.

Una funzione può essere invocata anche più volte e chiaramente in tal caso la porzione di codice verrà ripetuta tante volte quante sono le invocazioni.

In definitiva ogni funzione prende in ingresso un insieme di argomenti detti parametri e restituisce un valore.

Fino ad ora abbiamo utilizzato la funzione main(), che come abbiamo già detto, è la funzione che rappresenta il corpo del programma in C.

Banner Pubblicitario


Differenza tra procedure e funzioni in C

Innanzitutto occorre fare una distinzione tra procedure e funzioni.
Le funzioni in C ritornano un valore, se il valore di ritorno non è specificato, si assume per default int; se la funzione non ritorna alcun valore, allora si usa un ‘tipo speciale’ detto void, in questo caso parliamo di procedure.

La differenza sostanziale tra funzioni e procedure è dunque che le funzioni restituiscono un qualcosa mentre le procedure no.


Dichiarazioni di funzioni e procedure in C

Prima di utilizzare una funzione occorre dichiararla come si fa per le variabili. Ma, a differenza di quanto abbiamo visto per le variabili, non è sempre necessario dichiarare una funzione prima di poterla invocare.

La dichiarazione ci permette di capire unicamente come invocarla, ma non è obbligatoria. Essa infatti specifica quali e quanti argomenti prende in input, oltre al tipo del valore di ritorno.

La dichiarazione, detta anche prototipo della funzione, và fatta prima del main().

La sintassi è dunque questa:

<tipo_ritorno> nome_funzione ([<elenco_parametri>])

Banner pubblicitario

Dove:

<tipo_ritorno> è il valore di ritorno specificato, ricordiamo che se non viene specificato si assume per default int e se il tipo di ritorno è void si tratta di una procedura.

nome_funzione o nome_procedura è il nome che viene dato alla funzione o alla procedura. Si raccomanda di dare nomi sensati e di seguire le stesse regole sintattiche che si utilizzano per le variabili.

elenco_parametri rappresentano i valori in ingresso su cui agire, detti anche parametri formali.

Ecco quindi alcuni esempi di dichiarazione:

double cubo(float c);

int max(int x, int y);

int minimo(double x, y);

che equivale a: int minimo(double a, int b);
e non a: int minimo(double a, double b);

int fattoriale(int);

void stampa();  indica la dichiarazione della procedura stampa();

Una dichiarazione inoltre deve essere coerente con la definizione che la segue.


Definizione di funzioni e procedure in C

Prima di essere utilizzata una funzione deve essere o dichiarata o definita.

Una funzione viene definita o prima del main() se non è presente la dichiarazione, altrimenti può essere definita anche dopo il main().

Se il compilatore ad esempio trova una chiamata alla funzione prima della sua definizione, non sa quanti e di che tipo siano i parametri, quindi fa delle assunzioni e magari effettua dei casting, ma non sempre in maniera corretta.

Le funzioni in C ritornano un valore specificato e si definiscono in questo modo:

<tipo_ritorno> nome_funzione ([<elenco_parametri>])

{

<istruzioni>

return valore_restituito;

}

Dove:

per <tipo_ritorno>, nome_funzione o nome_procedura ed elenco_parametri valgono le stesse regole di prima.

Quindi tra le parentesi graffe si inseriscono le istruzioni e tra queste istruzioni assume particolare importanza return, che viene utilizzata per restituire un valore al chiamante. Il valore restituito però deve essere compatibile con il tipo restituito dalla funzione.

Facciamo dunque alcuni esempi.

Funzione che prende due interi e restituisce l’intero più grande:

int max(int x, int y)

{

if (x >= y)

return x;

else return y;

}

Esempio dove si verifica una conversione implicita. Si verifica quando il valore restituito non è coerente con il tipo_ritorno. In questo caso, infatti, la funzione PiGreco ritornerà il valore troncato a 3.

int PiGreco()

{

return 3.14;

}

Dunque, se non c’è coerenza tra il tipo di ritorno e il tipo dell’espressione passata a return, si applicano le regole di conversione implicita.

Quindi in definitiva o la dichiarazione (prototipo) o la definizione devono sempre precedere ogni utilizzo della funzione stessa.

N.B. Una funzione si può dichiarare all’interno di un’altra funzione, ma non si può definire. Dunque in C non si possono definire funzioni dentro funzioni.


Invocazione di una funzione o procedura in C

L’invocazione, ovvero la chiamata di funzione, è un’istruzione che permette l’esecuzione della funzione.

Esempi:

c=cubo(lato); viene invocata la funzione cubo su lato;

b=quadrato(x); viene invocata la funzione quadrato su x;

max=massimo(x,y); viene invocata la funzione massimo sui numeri x e y.


Facciamo adesso degli esempi molto semplici per capire meglio l’uso delle funzioni.


Esempio 1 di funzioni in C – funzione che calcola il volume di un cubo

Per quanto detto prima, per poter utilizzare un identificatore occorre dichiararlo, quindi inserisco:

double cubo(float); //dichiarazione o prototipo di funzione

In questo modo dichiaro la funzione cubo, prima del main(), che restituisce al programma un valore di tipo double e si dichiara che accetta in ingresso un solo argomento il cui tipo è float.
Quindi in questo caso la definizione della funzione può avvenire anche dopo l’invocazione.

double cubo(float c) //definizione di funzione
{
return c*c*c;
}

In alternativa, se ometto la dichiarazione, allora devo inserire la definizione della funzione prima del main().


Allego i due esempi. Il primo con la dichiarazione della funzione o prototipo:

#include <stdio.h>

double cubo(float);//prototipo o dichiarazione della funzione
main () {
  float lato;
  double c;
	
  printf("Inserisci il lato del cubo, calcolero' il volume:\n");
  scanf("%f", &lato);
	
  c=cubo(lato);	//invocazione della funzione
  printf("%.2f", c);
}

double cubo(float c) //definizione della funzione
{
   return c*c*c;
}

Seconda soluzione senza dichiarazione ma con la definizione

#include <stdio.h>

double cubo(float c) //definizione funzione cubo
{
   return c*c*c;
}

main ()
{
    float lato;
    double c;
	
    printf("Inserisci il lato del cubo, calcolero' il volume:\n");
    scanf("%f", &lato);
	
    c=cubo(lato);	//invocazione funzione cubo
    printf("%.2f", c);
}

Esempio 2 di procedura in C – visualizzare un messaggio

Un tipico esempio di procedure, ovvero di funzioni che non ritornano nessun valore, è quando dobbiamo visualizzare semplicemente un messaggio. Quindi un esempio banale è questo:

#include <stdio.h>

double cubo(float c) //definizione di funzione
{
    return c*c*c;
}

void stampa() //definizione di procedura
{    
    printf("Il volume e':\t");
}

main ()
{
	float lato;
	double c;
	
	printf("Inserisci il lato del cubo, calcolero' il volume:\n");
	scanf("%f", &lato);
	
	c=cubo(lato);  //invocazione di funzione
	stampa();	//invocazione di procedura
	printf("%.2f", c);
}

Esempio 3 – conto alla rovescia con le procedure

Facciamo un altro semplicissimo esempio sull’uso delle procedure. Realizzeremo quindi un programma che fa il conto alla rovescia utilizzando una procedura.

#include <stdio.h>

void contare(int j)  //definizione di procedura
{ 
	printf("%d\t", j);
}

int main() {
	int i;
	for (i=10; i>0; i--)
	    contare(i);  //invocazione procedura
	return 0;
}

Esempio 4 – uso delle funzioni per il calcolo del massimo fra 3 numeri

Facciamo adesso un altro semplice esempio che calcola il massimo tra 3 numeri, stavolta utilizzando le funzioni.

#include <stdio.h>

int  massimo(int x, int y, int z)
{
int max=x;
  if (y>max) max=y;
  if (z>max) max=z;
return max;
}

int main() {
  int a, b, c;
  printf("dammi 3 numeri:\n");
  scanf("%d %d %d",&a,&b,&c);
  printf("il massimo e': %d", massimo(a,b,c));
  return 0;
}


Esempio 5 – media di 10 numeri usando una funzione

Supponiamo di voler fare la media dei voti di 10 materie e utilizziamo una funzione somma che poi invocheremo per fare la media.

#include <stdio.h>
#define MATERIE 10

float somma() 
{
	int i;
	float s=0;

	float voto;
	for(i=0;i<MATERIE;i++){
		printf("inserisci il voto:\t");
		scanf("%f", &voto);
		s+=voto;
	}
	return s;
}

void stampa()
{
    printf("la media e':\t");
}

main ()
{
	float media;
        media=somma()/MATERIE;	
	stampa();
	printf("%.2f", media);
	
}

Chiaramente questi sono solo dei semplici esempi, più avanti approfondiremo ancora le funzioni in C.

N.B. Alcuni sinonimi del termine funzione sono procedura, sottoprogramma, routine e subroutine.

Alcuni link utili:

Funzione strlen() in C

Funzione gets() e puts() in C

Funzioni getchar() e putchar in C

Uso della libreria string.h

Concatenare due stringhe in C

Array di caratteri in C

Ricerca di un elemento in una matrice

Prodotto tra matrici in C

Somma tra due matrici in C

Array multidimensionali

Tavola pitagorica in C

Array o vettori in linguaggio C

Media dei numeri in un array in linguaggio C