Le funzioni - Soluzione

Da questo tutorial non verrà più presentato il codice completo della possibile soluzione, ma soltano le parti interessanti, che dovranno essere opportunamente integrate per fornire la soluzione completa e compilabile. Per ottenere un programma completo e funzionante, si tratta pertanto di scrivere la funzione main che dichiara le variabili necessarie e che chiama opportunamente le funzioni descritte.

Si supponga che siano dichiarate le seguenti macro:

#define MINVOTO 18
#define MAXVOTO 30
#define NVOTI   (MAXVOTO - MINVOTO + 1)
#define NMAX    100

Lettura dei voti

La seguente funzione riempie il vettore vet con n voti letti da tastiera. La funzione si preoccupa di verificare che i valori inseriti siano contenuti nell'intervallo richiesto.

void leggi_voti(int vet[], int n)
{
    char s[80];
    int i, voto;

    /* ciclo di lettura dei voti validi */
    i = 0;
    do {
        fgets(s, sizeof(s), stdin);
        voto = atoi(s);

    /* memorizzo il voto e incremento i solo se il voto è valido */
        if (voto >= MINVOTO && voto <= MAXVOTO) {
            vet[i] = voto;
            i++;
        }
    } while (i < n);
}

Il valore di n è passato per valore (S6.5), poiché non serve modificarne il valore ll'interno della funzione.

Il vettore vet è passato per riferimento (S6.6), in questo modo la funzione può modificarne i valori e questi saranno "visibili" anche dalla funzione chiamante (il main).

Stampa di un vettore

La funzione di stampa:

void stampa_vettore(int vet[], int n)
{
    int i;
    for (i = 0; i < n; i++)
        printf("%d\n", vet[i]);
}

ATTENZIONE: formulata in questo modo, può essere utilizzata sia per la stampa dei voti che per la stampa delle frequenze!
Basta passare i giusti argomenti (il vettore e la sua dimensione) alla funzione.

Calcolo del minimo valore nel vettore

Per il calcolo del minimo si può usare la seguente funzione:

int minimo(int vet[], int n)
{
    int i;
   
    min = vet[0];   // il minimo "iniziale" è primo valore del vettore
    for (i = 1; i < n; i++)
        if (vet[i] < min)
            min = vet[i];
    return min;
}

La funzione restituisce un valore int che è il minimo tra i valori presenti nel vettore.

NOTA: la funzione opera su un generico vettore di int composto da n elementi; può quindi essere usata non soltanto su un vettore di voti, ma su un qualsiasi vettore, indipendentemente dal significato dei valori in esso contenuti.

Riempimento del vettore delle frequenze

Le frequenze possono essere calcolate con la seguente funzione:

void frequenze(int vet[], int n, int freq[])
{
    int i;
    for (i = 0; i < n; i++)
        freq[vet[i] - MINVOTO]++;
}

Oltre a vet e n, viene passato per riferimento (il passaggio per riferimento è spiegato in S6.5) anche il vettore freq, che alla fine dell'esecuzione della funzione conterrà il conteggio (ovvero le frequenze) dei valori contenuti in vet; questo metodo viene usato in modo identico a quanto fatto in S6.8.

Non dimenticare di inizializzare a 0 tutti gli elementi del vettore che verrà passato come freq (come accade in S6.8), altrimenti il conteggio partirà da valori aleatori.

Individuazione dell'indice corrispondente al massimo valore

Per stampare il voto che ha frequenza massima, avendo utilizzato un vettore per memorizzare le frequenze come descritto al punto precedente, conviene andare a cercare l'indice dell'elemento di valore massimo nel vettore, invece che il valore massimo stesso:

int max_indice(int vet[], int n)
{
    int i, maxIndice = 0;
    for (i = 1; i < n; i++)
        if (vet[i] > vet[maxIndice])
            maxIndice = i;
    return maxIndice;
}

In questo modo, il voto con frequenza massima non è altro che il valore restituito da max_indice sommato a MINVOTO (che vale 18).