Capitolo precedente. Indice del capitolo. Indice analitico globale. Capitolo successivo.

Capitolo 2

Funzioni

2.1 Introduzione

Tutti i linguaggi di programmazione forniscono strumenti per poter scomporre problemi complessi in problemi più semplici. Ad esempio in Pascal si utilizzano le procedure e le function. In C si utilizzano le function. Anzi il C è stato pensato per rendere l'utilizzo delle function il più semplice possibile. Un programma deve essere pensato e realizzato come sequenza di funzioni semplici. Con alcuni accorgimenti è inoltre possibile nascondere i dettagli implementativi delle singole funzioni, utilizzare funzioni realizzate in precedenza per altri problemi, o addirittura estendere le potenzialità del linguaggio con la realizzazione di apposite librerie di function. Tutti questi problemi verranno trattati e approfonditi nei prossimi capitoli. In questo vedremo come dichiarare ed utilizzare funzioni per la risoluzione di semplici problemi.

Definizione: una function è un'unità di programma indipendente che, operando su dei dati avuti in ingresso, restituisce un risultato.

Questa definizione è simile al concetto matematico di funzione. Anche lì si può pensare alla funzione come ad una "macchinetta" che avuto in ingresso dei dati restituisce un risultato. I dati in ingresso non sono modificabili e vengono utilizzati per produrre il risultato.

2.2 Dichiarazione.

La dichiarazione delle function avviene indicando il tipo del risultato, il nome della function e le variabili in ingresso con il relativo tipo. Ad esempio

float area( float base, float altezza)

è la dichiarazione di una funzione che avuto in ingresso la base e l'altezza di un rettangolo restituisce l'area.

Base e altezza sono i due parametri di ingresso, detti parametri formali e vengono inizializzati al momento dell'utilizzo della function area.

Un altro esempio di dichiarazione è

int massimo( int a, int b, int c, int d)

dove massimo è una funzione che restituisce il massimo tra quattro numeri interi.

La dichiarazione di una funzione deve avvenire prima dell'utilizzo. Se questo non avviene il compilatore la considera di tipo int.

2.3 Chiamata di function.

Una funzione viene utilizzata all'interno di una espressione o di una operazione, indicandone il nome e i valori dei parametri. Ad esempio con

max=massimo(3, 5, 2, 8);

si assegna alla variabile max il valore 8. I parametri formali a, b, c, d sono in questo caso inizializzati con costanti.

Se si scrive

max=massimo(x, y, z, t);

determina il massimo tra quattro variabili x, y, z, t.

Nell'esempio precedente le variabili x, y, z, t sono dette parametri attuali. Con la chiamata si inizializzeranno a, b, c, d con i valori contenuti rispettivamente in x, y, z, t.

Il risultato di una function può essere utilizzato per inizializzare i parametri formali di un'altra function. Ad esempio

max=massimo( massimo(a,b,c,d), massimo(a1,b1,c1,d1), massimo(a2,b2,c2,d2), massimo(a3,b3,c3,d3));

determina il valore massimo tra 16 numeri. Nel caso di funzioni utilizzate per inizializzare i parametri formali di altre funzioni, il compilatore C assicura solo che tutti i parametri formali siano inizializzati prima della chiamata, ma non esiste alcuna possibilità di stabilire l'ordine dell'inizializzazione.

L'associazione tra parametri formali e parametri attuali avviene in base alla posizione nella chiamata di funzione. È importante che i parametri formali e quelli attuali corrispondenti siano dello stesso tipo per non incorrere in errori alle volte difficili da rilevare. Il meccanismo di associazione è sempre per valore: il parametro formale viene inizializzato con il valore del parametro attuale.

Questo significa che il valore originale del parametro attuale non viene modificato da una function.

2.4 Il corpo della function.

Il corpo della function è un'istruzione composta contenente le dichiarazione di variabili, dette variabili locali, e le istruzioni che descrivono i compiti della funzione. Il valore che deve essere restituito da una funzione è indicato dall'istruzione return.

La sintassi dell'istruzione return è la seguente

return espressione;

dove espressione indica il valore che deve essere restituito. Se espressione non compare o se non compare l'istruzione return il valore restituito dalla funzione è indefinito.

Esempi.

1. Calcolare l'area di un rettangolo..

2. Calcolare il massimo tra quattro numeri.

3. Scrivere la function maiuscolo che avuto in ingresso un carattere restituisce il corrispondente carattere maiuscolo..

4. Scrivere la function per risolvere un'equazione di primo grado ..

5. Scrivere una function che, avuto in ingresso un numero intero positivo, restituisce 1 se primo, 0 altrimenti..

6. Scrivere una function che calcoli il fattoriale di un numero..

7. Calcolare la potenza n-esima di un numero..

2.6 void.

Una funzione potrebbe non aver bisogno di parametri in ingresso per svolgere il proprio compito. Ad esempio la funzione per calcolare l'errore relativo non necessita di parametri in ingresso: deve svolgere il proprio compito e restituire il risultato dell'elaborazione. In questi casi la dichiarazione della funzione avviene utilizzando il tipo void tra le parentesi.

8. Calcolare l'errore relativo..

Utilizzando la dichiarazione

double errore (void) il compilatore è in grado di segnalare se la funzione viene utilizzata con dei parametri in ingresso.

Similmente anche una funzione può essere dichiarata di tipo void. In questo caso significa che tale funzione svolge un compito e non deve restituire alcun valore. Ad esempio supponiamo di volere una funzione che, avuto in ingresso tre valori visualizzi un messaggio particolare insieme ai valori. In questo caso la funzione svolge un compito e non deve restituire nulla.

void stampa( float a, float b, float c ) {
printf("Primo lato = %f\nSecondo lato = %f\nTerzo lato = %f\n\n\nVolume = %f\n", a, b, c, a*b*c);
}

Si deve notare che non è stata utilizzata l'istruzione return.

2.7 Il programma.

Definizione: un programma è una sequenza di funzioni, comprendenti sempre una ed una sola funzione chiamata main. Questa funzione sarà eseguita per prima.

Questo significa che main è a tutti gli effetti una funzione. Quindi deve essere dichiarata come tutte le funzioni, con parametri in ingresso e con parametri in uscita. Le dichiarazione di main fatte nel capitolo 1 erano perciò imprecise perchè non avevano indicazioni sui parametri in ingresso e non veniva specificato il tipo di main, con la conseguenza che il compilatore la considerava di tipo int. Spiegheremo meglio come sfruttare i parametri in ingresso a main nei prossimi capitoli. Per ora ci accontenteremo di modificare la dichiarazione di main in questo modo:

void main( void )

che significa che main non restituisce valori e non ha parametri in ingresso.

Esempio:

9. scrivere un programma che, richiesti tre valori,calcoli il volume del parallelepipedo e lo stampi..

2.8 Approfondimento su input e output.

Abbiamo già detto nel capitolo 1 che in C non esistono istruzione per l'input/output ma si devono utilizzare delle estensioni, diverse per oni sistema operativo, che aggiungono al linguaggio stesso nuove possibilità.

Abbiamo introdotto allora due di queste estensioni, printf e scanf senza scendere nei dettagli. Ora però possiamo spiegare il termine estensione. In realtà si sono utilizzate due funzioni predefinite. Vediamole nei dettagli:

scanf: la funzione scanf è così dichiarata:

int scanf( const char *formato [,argomenti]... );

I parametri in ingresso sono il formato, dichiarato come una stringa costante, e 0, 1 o più argomenti.

La funzione scanf legge i dati dallo standard input, e li pone nelle locazioni di memoria indicate dagli argomenti, procedendo alla conversione in base al formato. Infatti tutti i dati forniti in ingresso sullo standard input sono caratteri ed è attraverso il formato che avviene la conversione nel tipo corrispondente alla variabile.

Il formato di controllo può contenere uno o più dei seguenti caratteri:

La funzione scanf restituisce il numero di conversioni corrette effettuate. Scanf restituisce il valore costante EOF quando non ci sono dati da convertire.

printf: la funzione printf è così dichiarata:

int printf( const char *format [, argument]... );

La funzione printf stampa una serie di caratteri convertiti in base al formato, sullo standard output. Nella stringa di formato possono comparire oltre alle indicazioni per la conversione, qualsiasi sequenza di caratteri, che viene fedelmente inviata allo standard ouput.

Ad esempio

printf("Line one\n\t\tLine two\n");

produce in uscita

Line one

Line two

Per ogni argomento che segue la stringa di formato deve essere indicata nella stringa di formato stessa il tipo di conversione da effettuare. Se compaiono più argomenti delle indicazioni di conversione, gli argomenti extra sono ignorati, mentre se gli argomenti sono in numero minore rispetto al formato di conversione allora il risultato sarà indefinito.

La funzione printf restituisce il numero di caratteri stampati, oppure un valore negativo in caso di errore.

Esempi:

1. Lettura e scrittura.

void main( void ) {
int i;
float fp;
char c;
int result;
printf( "Enter an integer, a floating-point number, a character:\n" );
result = scanf( "%d %f %c ", &i, &fp,&c, s );
printf( "\nThe number of fields input is %d\n", result );
printf( "The contents are: %d %f %c %s\n", i, fp, c, s );
}

10. Somma di n numeri interi.