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.
Il C#, che non è da meno, ne mette a disposizione quattro, che sono:

  • while
  • do
  • for
  • foreach

 

  • while

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.

N.R.

Codice sorgente Tabellina.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

// questo programma calcola la tabellina 
 
using System;
class Tabellina
      {
          public static void Main()
               {
                 // dichiaro la variabile i
                 // che fa da contatore che parte da 1 
                 int i=1;
      
                // variabile che contiene il numero digitato
                int num=0;
      
               // stampo il messaggio per l'utente
               Console.Write("Inserisci il numero (max 10) = ");
              
               // leggo il numero da tastiera ed eseguo la 
               // conversione a numero intero
               num=Convert.ToInt32(Console.ReadLine());
     
               // eseguo il ciclo  while
               while(i<=10)
               {
                  Console.WriteLine("\n {0} x {1}= {2}",i,num,num*i);
                   // incremento il contatore
                   ++i;
                }
      
                // attendo un carattere  qualsiasi
                // digitato per chiudere il programma
                Console.ReadLine();
                }
        } 

 

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.

  • do

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.

N.R.

Codice sorgente Tabellina2.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

 // questo programma calcola la tabellina con il do 
  
using System;
class Tabellina
     {
         public static void Main()
           {
              // dichiaro la variabile i
              // che fa da contatore che parte da 0
              int i=0;
      
              // variabile che contiene il numero digitato
              int num=0;
              
              // stampo il messaggio  per l'utente
             Console.Write("Inserisci il numero (max 10) = ");
             
               // leggo il numero da tastiera ed eseguo la 
              // conversione a numero intero
              num=Convert.ToInt32(Console.ReadLine());
              // eseguo il ciclo do
              do
              {
                    // incremento il contatore e poi stampo
                    ++i;
                    Console.WriteLine("\n {0} x {1}= {2}",i,num,num*i);
               
               } while(i<10);

// attendo un carattere qualsiasi // digitato per chiudere il programma Console.ReadLine(); } }

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.

  • for

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
      }
  • abbiamo dichiarato una variabile assegnandole il valore iniziale 1: int i=1;
  • abbiamo imposto il test: i<=10;
  • ne abbiamo incrementato il valore: i++ .

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:

N.R.

Codice sorgente Tabellina3.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// questo programma calcola la tabellina con il for 
     
 using System;
class Tabellina
      {
          public static void Main()
            {
      
               // variabile che contiene il numero digitato
               int num=0;
      
              // stampo il messaggio per l'utente
             Console.Write("Inserisci il numero (max 10) = ");
      
             // leggo il numero da tastiera ed eseguo la 
             // conversione a numero intero 
             num=Convert.ToInt32(Console.ReadLine());
      
             // eseguo il ciclo for
             for(int i=1; i<=10; i++)
                { 
                    Console.WriteLine("\n {0} x {1}= {2}",i,num,num*i);
                 } 
     
            // attendo un carattere qualsiasi
            // digitato per chiudere il programma 
           Console.ReadLine();
            }
      }

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.

  • foreach

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......

Pagina precedente - Pagina successiva