Invocare Funzioni in Linguaggio C

Entriamo nel dettaglio di come invocare una funzione in linguaggio C.

In questa lezione vedremo come chiamare o invocare una funzione in linguaggio C. Quando si invoca una funzione, si passano i valori degli argomenti alla funzione e, se la funzione restituisce un valore, possiamo utilizzare il risultato della funzione come parte di un'espressione.

Chiamata a Funzione

Una chiamata di Funzione in linguaggio C consiste nell'inserire il nome della funzione seguito dalla lista di argomenti separati da virgole e racchiusi tra parentesi.

Ad esempio:

somma(x, y);
differenza(10, 4);
stampa_messaggio();
Nota

Le parentesi devono essere sempre presenti

Quando si invoca una funzione, la lista di argomenti deve essere presente sempre anche se vuota.

Ad esempio, se abbiamo una funzione che non accetta parametri, dobbiamo comunque inserire le parentesi vuote:

stampa_messaggio();

In caso contrario, ciò che accade è che otteniamo un'istruzione valida ma senza alcun effetto. I compilatori moderni, tuttavia, generano un warning per segnalare questo problema:

/* ERRORE: Nessun effetto */
stampa_messaggio;

Quando si invoca una funzione che non restituisce alcun risultato, quindi una funzione void, basta far seguire l'invocazione della funzione da un punto e virgola ottenendo, così, una istruzione.

stampa_messaggio();

Viceversa, se una funzione restituisce un valore, possiamo utilizzare il risultato della funzione come parte di un'espressione.

int risultato = somma(10, 20);

Il valore restituito dalla funzione somma verrà assegnato alla variabile risultato.

Un valore di ritorno di una funzione può essere anche ignorato. Questo è utile quando il valore restituito non è necessario per il programma.

somma(10, 20);

Ovviamente, in questo esempio, risulta alquanto strano ignorare il risultato di una somma, ma in generale, questa tecnica può essere utile in situazioni in cui il valore restituito non è necessario.

Ad esempio, la funzione printf restituisce il numero di caratteri stampati, ma spesso non è necessario utilizzare questo valore. Nei programmi che abbiamo scritto finora, abbiamo ignorato il valore restituito da printf.

/* Prendiamo il numero di caratteri stampati */
int num_caratteri = printf("Hello, World!\n");

/* Ignoriamo il valore restituito */
printf("Hello, World!\n");

Ignorare il valore di ritorno di una funzione non è un errore. Potrebbero sorgere, però, situazioni in cui vogliamo esplicitare il fatto che il valore restituito non è utilizzato. Per farlo è necessario, semplicemente, effettuare il cast a void del valore restituito.

/*
 * Ignoriamo esplicitamente
 * il valore restituito
 */
(void) printf("Hello, World!\n");

Utilizzare questo cast esplicito può diventare pesante, perché ogni volta che si ignora il valore di ritorno di una funzione, è necessario scrivere (void). Per questo motivo, è più comune ignorare il valore di ritorno senza effettuare il cast. Procederemo in questo modo nel resto della guida.

Ricapitolando:

Definizione

Chiamata a Funzione

In linguaggio C, per chiamare o invocare una funzione è necessario scrivere il nome della funzione seguito dalla lista di argomenti racchiusi tra parentesi e separati da virgole.

nome_funzione(arg1, arg2, arg3);

Se la funzione non accetta argomenti, è necessario inserire le parentesi vuote:

nome_funzione();

Se la funzione restituisce un valore, possiamo utilizzare il risultato come parte di un'espressione:

tipo_risultato risultato = nome_funzione(arg1, arg2);

Il valore restituito da una funzione può essere ignorato:

nome_funzione(arg1, arg2);

Esempio

Vediamo un esempio di chiamata a funzione e combinazioni di chiamate a funzione con espressioni.

Definiamo una funzione differenza che restituisce la differenza di due numeri in virgola mobile:

double differenza(double a, double b) {
    return a - b;
}

Poi definiamo quadrato che restituisce il quadrato di un numero floating point:

double quadrato(double a) {
    return a * a;
}

Possiamo combinare le chiamate a queste due funzioni per creare un programma che calcola la distanza tra due punti su un piano date le loro coordinate:

#include <stdio.h>
#include <math.h>

double differenza(double a, double b) {
    return a - b;
}

double quadrato(double a) {
    return a * a;
}

double distanza(double x1, double y1, double x2, double y2) {
    double dx = differenza(x2, x1);
    double dy = differenza(y2, y1);
    return sqrt(quadrato(dx) + quadrato(dy));
}

int main() {
    double x1, y1, x2, y2;

    printf("Inserisci le coordinate del primo punto: ");
    scanf("%lf %lf", &x1, &y1);

    printf("Inserisci le coordinate del secondo punto: ");
    scanf("%lf %lf", &x2, &y2);

    double d = distanza(x1, y1, x2, y2);

    printf("La distanza tra i due punti è: %lf\n", d);

    return 0;
}

In questo esempio, la funzione distanza calcola la distanza tra due punti (x1, y1) e (x2, y2) utilizzando le funzioni differenza e quadrato:

double distanza(double x1, double y1, double x2, double y2) {
    double dx = differenza(x2, x1);
    double dy = differenza(y2, y1);
    return sqrt(quadrato(dx) + quadrato(dy));
}

Nella funzione abbiamo anche usato la funzione di libreria standard sqrt per calcolare la radice quadrata di un numero.

Questo esempio mostra come le chiamate di funzioni possono essere combinate per creare programmi più complessi.

Nota

Compilazione con la libreria Matematica

Per compilare il programma di esempio, se ci troviamo su un sistema Unix-like come Linux, è necessario aggiungere l'opzione -lm al comando di compilazione:

gcc -o distanza distanza.c -lm

Questo è necessario perché la funzione sqrt è definita nella libreria matematica libm. Aggiungendo l'opzione -lm, diciamo al compilatore di collegare il programma con la libreria matematica.

Questo non è necessario se stiamo compilando sotto Windows con il compilatore Visual Studio.

In Sintesi

In questa lezione abbiamo visto qual è la sintassi per invocare una funzione in linguaggio C:

  • Un'invocazione a funzione è composta dal nome della funzione seguita dalla lista di argomenti separati da virgole e racchiusi tra parentesi.
  • Le parentesi devono essere sempre presenti, anche se vuote.
  • Se la funzione restituisce un valore, possiamo utilizzare il risultato come parte di un'espressione.
  • Il valore restituito da una funzione può essere ignorato.

Abbiamo anche visto un esempio di come le chiamate a funzioni possono essere combinate per creare programmi più complessi.

Nella prossima lezione studieremo un aspetto importante delle funzioni in C: la dichiarazione di funzioni.