Durante queste settimane inevitabilmente le attività di PCTO vengono svolte in parte in presenza ed in parte in remoto. Le lezioni in remoto vengono ovviamente utilizzate per risolvere dubbi e spiegare qualcosa di nuovo che possa essere di aiuto ai ragazzi. Ultimamente alcuni mie studenti di classe 3′ sono impegnati chi nella realizzazione di serre idroponiche e chi nel simulare il funzionamento di un’incubatrice neonatale, in entrambe le situazioni bisogna rilavare grandezze fisiche, come ad esempio la temperatura. Spesso è necessario leggere dai sensori in un determinato intervallo di tempo una sequenza di valori che dovranno essere memorizzati in un array e successivamente elaborati.
Come detto sopra, è spesso utile memorizzare una sequenza di numeri, ad esempio una sequenza di letture di temperatura, all’interno di un array e poi dalla lista estrarre il valore che ci interessa, ad esempio: la massima temperatura, la minima temperatura, la media, ecc…
Per fare questa operazione il metodo più semplice ed intuitivo consiste nello leggere la sequenza dei valori per cercare il più grande.
Ma come costruire un algoritmo per fare questa operazione?
Riprendo un esempio che facevo tempo fa ai ragazzi declinato da alcune spiegazioni di un vecchio libro di informatica su cui studiai io 🙂
Immaginate la seguente situazione:
il mio collega con cui lavoro in compresenza, che chiamerò Prof. Rossi, mi detta la lista dei voti assegnati ad uno di voi, non mi dice in anticipo quanti voti mi detterà, me li detta ed io devo costruire un algoritmo che mi permetterà di dire al collega qual è il voto più altro nel momento in cui mi dirà:
“basta non ci sono più voti!”,
istantaneamente, senza rileggere tutta la lista devo fornire questa informazione al collega.
Partiamo!
- Il primo voto che mi viene dettato è “3.5”, allora lo scriverò su un foglio di carta;
- il secondo voto è 6.75 che è più grande di 3 quindi potrebbe essere questo il massimo dei voti, cancello 3.5 e scrivo sulla pagina il 6.75;
- subito dopo mi viene detto: “5.5” che è più piccolo di 6.75 quindi non potrà essere questo il voto più alto, lasceremo scritto sul foglio 6.75;
- mi viene detto: “9” ed essendo più grande di 6.75 lo indico sul mio foglio, cancellando il 6.75;
- il voto successivo è 7.25, che è inferiore al 9 e non lo riporto sul foglio;
- il voto successivo è 8.75, che è inferiore al 9 e non lo riporto sul foglio;
- Il Prof. Rossi mi avvisa che ha finito di dettarmi i voti ed io dirò immmediatamente che il voto massimo è 9;
Come possiamo tradurre in C questo algoritmo?
Realizziamo un Array in cui inserire la sequenza dei 6 voti:
sequenzaVoti[] = {3.5, 6.75, 5.5, 9, 7.25, 8.75};
Il passo successivo sarà quello di definire un contenitore (una variabile) in cui di volta in volta andremo a memorizzare il numero più grande che abbiamo trovato.
Definisco quindi “votoMassimo” la variabile che contiene il voto massimo temporaneo (quello che nell’esempio mi veniva dettato dal Prof. Rossi)
float votoMassimo = 0;
Sarà necessario utilizzare un ciclo for per leggere uno alla volta i voti della lista.
Il ciclo parte con indice 0 arrivando fino alla fine dell’array, cioè con indice pari a n-1 (n: dimensione dell’array), quindi l’array è costituito da n oggetti e l’indice che identifica la posizione va da 0 a n-1.
In C è possibile calcolare automaticamente la dimensione dell’array con la funzione: sizeof di cui trovate tutte le informazioni sul references di Arduino
sizeof(sequenzaVoti)/sizeof(float))
mi darà la dimensione n dell’array.
Approfondiamo quanto detto.
sizeof permette di ottenere la dimensione in byte di una variabile di qualsiasi tipo (int, float, byte, char, ecc…) o del numero di byte che occupa un array.
Attenzione però per definire un array possiamo farlo in due modi:
modo 1, indicando la dimensione tra parentesi quadre
float sequenzaVoti[6]
modo 2, enumerando gli elementi, nel nostro caso i voti, ovvero l’elenco degli oggetti
float sequenzaVoti[] = {3.5, 6.75, 5.5, 9, 7.25, 8.75};
Per sapere la dimensione in byte dell’array useremo sizeof() che restituirà la dimensione dell’array in byte.
Quindi l’operatore sizeof(sequenzaVoti) non restituirà il numero di celle dell’array, ma la sua dimensioni in byte, pertanto:
sizeof(sequenzaVoti)
restituirà come valore: 24 perchè l’array sequenzaVoti[] è costituita da 6 numeri reali (con la virgola), ciascuno di esso rappresentato da quattro byte pertanto il numero totale di byte dell’array è 6×4=24.
Per calcolare la dimensione dell’array, partendo dalla dimensione in byte ricavata da sizeof(), possiamo operare in questo modo:
for (int i = 0; i < (sizeof(sequenzaVoti)/sizeof(float)); i++) {
//codice…
}
Per trovare il voto massimo bisogna verificare ad ogni ciclo del for se il valore attuale (sequenzaVoti[i]) risulta maggiore del valore che abbiamo memorizzato all’interno della variabile votoMassimo, per fare questo controllo utilizzeremo l’istruzione if:
if (sequenzaVoti[i] > votoMassimo) {
// salviamo il valore massimo attuale...
}
Se la condizione dell’if è verificata, bisogna sovrascriviamo il valore di “votoMassimo” con quello trovato della sequenza dei voti che stiamo leggendo.
votoMassimo = sequenzaVoti[i];
Detto ciò costruiamo lo sketch che, data una lista di 6 voti memorizzati in un array, stampa sulla serial monitor
Il voto massimo è:…
al posto dei puntini dovete stampare il voto massimo tra quelli scritti nell’array.
La lista dei voti, per ora, viene inserita nel codice, non dovrà essere scritta da computer sulla serial monitor.
Potete far eseguire tutto il codice di estrazione del voto massimo nel setup() con il loop() vuoto.
Per completezza con quanto spiegato, aggiungo alla stampa del voto massimo la stampa della dimensione massima dell’array sequenzaVoti[]
Il listato completo sarà:
/*
* Prof. Michele Maffucci
* data 15.03.2021
*
* Trovare il valore più grande in un array
*
*/
// sequenza di 6 voti di uno studente
float sequenzaVoti[] = {3.5, 6.75, 5.5, 9, 7.25, 8.75};
void setup() {
Serial.begin(9600);
// la variabile con il numero massimo:
int votoMassimo = 0;
for (int i = 0; i < (sizeof(sequenzaVoti) / sizeof(float)); i++) {
if (sequenzaVoti[i] > votoMassimo) {
// se il voto corrente è maggiore di quello
// salvato dentro votoMassimo allora lo copio
votoMassimo = sequenzaVoti[i];
}
}
Serial.print("Il voto massimo è: ");
Serial.println(votoMassimo);
Serial.print("Dimensione in byte dell'array ");
Serial.println(sizeof(sequenzaVoti));
}
void loop() {}
Esercizio 1
Realizzare uno sketch che accetta l’imputo dei voti (float) da tastiera e restituisce il voto massimo.
Esercizio 2
Realizzare uno sketch che accetta l’imputo dei voti (float) da tastiera e restituisce la media dei voti.
Buon Coding a tutti 🙂