In molte applicazioni, a volte, è necessario ripetere blocchi
di codice più volte. Tutti i linguaggi di programmazione mettono
a disposizione per le iterazioni una serie di istruzioni ad hoc.
Questa istruzione consente di ripetere un blocco di codice fintanto che una determinata condizione viene verificata (true). Il suo costrutto è questo: while (condizione) { // istruzioni } Dal diagramma si osserva facilmente che il blocco contenente le istruzioni viene eseguito fino a quando il risultato della valutazione della condizione risulterà falso (false). Solo allora il flusso prosegue eseguendo l’istruzione successiva al ciclo while. E’ ora di provare l’istruzione while. Faremo un programmino che ci calcola la tabellina di un numero digitato da tastiera. Tale numero non dovrà essere più grande di 10. Il listato che segue consente di calcolare la tabellina di un numero digitato da tastiera. Copiatelo ed eseguitelo.
L’istruzione while della riga 23, testa la condizione tra parentesi ed esegue il blocco di codice contenuto tra le parentesi graffe, fino a quando il contatore i diventa maggiore di 10. A questo punto la condizione diventa falsa (false) ed il ciclo termina passando il controllo all’istruzione della riga 32. Una breve considerazione merita l’istruzione della riga 25. I parametri {0}, {1} e {2} fanno riferimento, per la stampa, rispettivamente alle variabili i, num ed il calcolo diretto num*i. Per quest’ultimo, non ho utilizzato una variabile per memorizzare il risultato dell’operazione, ma l’ho passata direttamente affinchè venisse stampato il risultato. Questo solo a dimostrazione di come sia versatile il metodo WriteLine (in genere il metodo Write) della classe Console. Infine, un costrutto while può essere interrotto in base ad una eventuale condizione interna al blocco di codice con l’istruzione break. Per esempio, avrei potuto (anche se non ha molto senso) interrompere il ciclo while del codice precedente non appena il il risultato dell’operazione num*i fosse diventato maggiore di 25, in questo modo: ... // eseguo il ciclo while while(i<=10) { if ((num*i)>25) break; // interrompo Console.WriteLine("\n {0} x {1}= {2}",i,num,num*i); // incremento il contatore ++i; } L’istruzione break interrompe il ciclo e passa il controllo all’istruzione immediatamente successiva al ciclo stesso. Questa prassi potrebbe risultare più utile in quei casi in cui è ignoto il numero di iterazioni da effettuare. Potremmo utilizzare un costrutto simile al seguente: ... // eseguo il ciclo while che è sempre verificato while(true ) { if ( condizione) break; // interrompo // codice } .... il test del while è sempre vero (true) quindi il ciclo prosegue ad iterare fino a quando la condizione dell’istruzione if risulta verificata.
A volte è necessario fare eseguire il blocco di codice, all’interno di un ciclo, almeno una volta. Nel ciclo while, che abbiamo visto in precedenza, il blocco di codice al suo interno, potrebbe non essere mai eseguito. Ciò può verificarsi se il test risulta falso (false) proprio quando l’istruzione viene eseguita per la prima volta. Per avere la sicurezza che il blocco di codice venga eseguito almeno una volta, ci affidiamo al costrutto do, in questo modo: do { // istruzioni }while(condizione); Il costrutto denota subito che le istruzioni vengono eseguite prima che venga testata la condizione che se risulta vera (true), ripeterà il blocco di codice. La situazione si ripete fino a quando il test risulterà falso (false). Questo è il suo diagramma di flusso: Trasformiamo ora il codice del programma precedente in modo tale da utilizzare il costrutto do. Copiate il codice del listato ed eseguitelo come sapete.
Nel listato c’è poco da commentare tranne per il test while(i<10). Come notate, rispetto al listato precedente, nel test è sparito il simbolo "=" perché dal momento in cui il contatore "i", che ora parte da 0, assume come valore 10, vuol dire che è stato raggiunto l’ultimo valore e dopo aver effettuato la stampa delle variabili e del calcolo, il test risulterà falso (false), quindi il programma prosegue con la prima istruzione dopo il ciclo (riga 32). Inoltre il contatore "i" viene incrementato prima della stampa in modo tale da avere una numerazione esatta da 1 a 10 appunto. Domanda: "Che cosa sarebbe successo se l’incremento del contatore "i" fosse stato lasciato dopo l’istruzione di stampa (riga 26) ?" Provateci da soli e avrete la risposta.
Nei cicli che abbiamo descritto in precedenza, abbiamo fatto uso di contatori che in qualche modo hanno influenzato l’andamento dei cicli stessi. Infatti abbiamo inizializzato una variabile contatore, ne abbiamo verificato il valore, ne abbiamo incrementato il valore, ecc. tutto con istruzioni separate. Con il ciclo for facciamo praticamente le stesse cose ma con un unico costrutto: for(contatore; condizione; incremento) { //istruzioni } per esempio: for(int i=1; i<=10; i++) { // istruzioni }
Come vedete abbiamo riunito in un unico costrutto tutto il necessario per eseguire un ciclo con 10 iterazioni. Il suo diagramma di flusso: Adesso sostituendo il ciclo del listato precedente con il nuovo ciclo for, ecco come appare il sorgente del programma Tabellina:
A titolo di esercizio, provate a "decifrare" tutti i cambiamenti che ho introdotto nel listato. Un’ultima considerazione sull’istruzione for; l’istruzione seguente: for(int i=1; int z=0; z*i<=150; i++; z++) { // istruzioni } ci consente di utilizzare più di una variabile (i e z) e tutte insieme possono essere utilizzate per testare la condizione. In questo esempio, sono state utilizzate in una operazione il cui risultato deve essere al massimo 150.
Questa è l’ultima istruzione iterativa del gruppo. Essa è molto simile all’istruzione for ma viene utillizzata per iterare all’interno di collezioni, come gli Array. Le collezioni sono un argomento che tratteremo più avanti, quindi per il momento sono costretto a rimandare la sua descrizione ad un’altra lezione in cui si parlerà appunto di Array. Nella prossima lezione entreremo nel vivo della programmazione ad oggetti, parleremo di classi. Questo è il più importante argomento che affronteremo e che sarà suddiviso in molte lezioni con difficoltà crescente, quindi chi ben incomincia...... |