I vettori - Soluzione
Un esempio di soluzione per l'esercizio sui vettori è il seguente:
#include <stdlib.h>
#include <stdio.h>
#define MINVOTO 18
#define MAXVOTO 30
#define NVOTI (MAXVOTO - MINVOTO + 1)
#define NMAX 100
int main() {
char s[80];
int n;
int voti[NMAX];
int i, voto;
/* input dei dati */
fgets(s, sizeof(s), stdin);
n = atoi(s);
/* se n <= 0 stampo una stringa di errore ed esco */
if (n <= 0 || n > NMAX) {
printf("[RISULTATO]\nerrore\n");
/* NOTA: sarebbe bene restituire un numero != 0, ma pvcheck da errore */
return 0;
}
/* 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) {
voti[i] = voto;
i++;
}
} while (i < n);
/* stampa valori */
printf("[VALORI]\n");
for (i = 0; i < n; i++)
printf("%d\n", voti[i]);
/* minimo */
int min = voti[0];
for (i = 1; i < n; i++)
if (voti[i] < min)
min = voti[i];
printf("[MINIMO]\n");
printf("%d\n", min);
/* frequenze */
int freq[NVOTI] = {0};
for (i = 0; i < n; i++)
freq[voti[i] - MINVOTO]++;
printf("[FREQUENZE]\n");
for (i = 0; i < NVOTI; i++)
printf("%d\n", freq[i]);
/* indice del voto piu` frequente */
int maxIndice = 0;
for (i = 1; i < NVOTI; i++)
if (freq[i] > freq[maxIndice])
maxIndice = i;
/* devo sommare MINVOTO a maxIndice per ottenere il voto */
printf("[MAXFREQ]\n");
printf("%d\n", maxIndice + MINVOTO);
return 0;
}
Commenti
Il funzionamento del programma è molto lineare:
- all'inizio sono dichiarate una serie di macro, con le direttive
#define
, che definiscono le costanti relative ai limiti dei valori necessari- le macro sono utili per evitare di inserire direttamente nel codice i cosiddetti numeri magici, che rendono problematica la comprensione del codice e eventuali successive modifiche
- il valore di
n
viene letto da testiera, e il costruttoif
successivo serve a terminare il programma qualora il valore non sia compreso nell'intervallo[1,NMAX]
- il controllo è necessario in quanto il vettore
voti
viene dimensionato per memorizzareNMAX
elementi
- il controllo è necessario in quanto il vettore
- il ciclo
do-while
permette di leggere i valori dei voti- si noti che l'indice
i
che conteggia il numero di voti validi letti viene incrementato solo nel caso in cui il voto letto sia corretto (quindi all'interno del costruttoif
annidato neldo-while
)
- si noti che l'indice
- la stampa dei valori (marcatore
[VALORI]
) è un semplice ciclofor
da0
an-1
che stampa tutti i valori nel vettorevoti
Per cercare il minimo
- viene assegnato alla variabile
min
il valore del primo elemento del vettorevoti[0]
- con un ciclo
for
si controllano tutti i voti successivi al primo - se si trova un valore inferiore a
min
ne si aggiorna il valore - alla fine si stampa il valore
min
Il calcolo della frequenza dei voti è interessante:
- l'istruzione
freq[voti[i] - MINVOTO]++
incrementa di1
l'elemento del vettorefreq
di indicevoti[i]-MINVOTO
voti[i]
è il valore del voto corrente, mentreMINVOTO
è il valore minimo (18
)- pertanto e il voto vale
18
verrà incrementato il valore di indice0
, se vale19
quello di indice1
, ... e se vale30
il valore di indice13
Infine, per il calcolo del massimo delle frequenze:
- si opera come per il minimo, ma invertendo il test per cercare il massimo, e analizzando il vettore
freq
invece chevoti
- da notare che in questo caso non si tiene traccia del valore massimo, ma dell'indice del valore massimo
- tale indice viene poi utilizzato alla fine per recuperare il valore massimo dal vettore
Hands-on
La soluzione che include anche il calcolo richiesto dai due seguenti hands-on è vettori-completo.test.
Il programma completo si può testare con
pvcheck -f vettori-completo.test ./a.out
Modifica la soluzione dell'esercizio per calcolare anche il massimo dei voti.
Stampi a video il massimo calcolato usando il formato:
[MASSIMO]
28
Suggerimenti
Si proceda come per il minimo, modificando opportunamente i test necessari.
Scopri un esempio di soluzione »Modifica la soluzione dell'esercizio per calcolare anche il voto medio.
Stampa a video la media dei voti usando il formato:
[MEDIA]
23.7
Suggerimenti
Come si vede nell'esempio di output, viene richiesto di stampare un numero con una sola cifra dopo la virgola; per farlo utilizzare lo specificatore di formato %.1f
nella printf
(gli specificatori di formato sono trattati in S2.12).
Il calcolo della media richiede la somma di tutti i valori, che viene divisa per il numero di valori sommati. Presta attenzione ai seguenti aspetti:
- la divisione non deve essere fatta tra interi, in quanto il risultato verrebbe arrotondato
- si può utilizzare un totale di tipo
double
, oppure fare il cast da intero adouble
in modo opportuno
Per calcolare la somma si usi un ciclo for
(S4.6) e una variabile (es. totale
) nella quale sommare il valore di tutti i numeri nel vettore.
ATTENZIONE: non dimenticare di inizializzare la variabile totale
assegnando il valore 0
(zero).
Cosa succederebbe altrimenti?