Indice del libro


I cicli modifica

I cicli sono una serie di "azioni" ripetute "fino a" o "un certo numero di volte". Le azioni sono contenute in un blocco.Ogni volta che si esegue un blocco viene detto "iterazione". Ognuno di questi costrutti ha un elemento decisionale che serve a determinare la fine del ciclo.

NOTA: non è obbligatorio che in ciclo finisca.

For modifica

Il ciclo for è quello più comune a molti linguaggi. Da questo è possibile ottenere delle altre tipologie ma nell'uso generale si preferisce utilizzarlo quando il numero di iterazioni è noto. La sua sintassi è la seguente:

 
 for ( <inizio> ; <condizione> ; <incremento> )
 {
    ... istruzioni ...
 }

vediamo un esempio [ciclo finito]:

 my $max_valore = 10;
 
 my $b;
 for ( $b = 0 ; $b < $max_valore ; $b++ )
 {
    print "iterazione numero $b\n";
 }
 print "b=$b\n";

che produrrà :

iterazione numero 0
iterazione numero 1
iterazione numero 2
iterazione numero 3
iterazione numero 4
iterazione numero 5
iterazione numero 6
iterazione numero 7
iterazione numero 8
iterazione numero 9
b=10

vediamo ora che cosa succede se togliamo la condizione (CTRL+C per fermare) [ciclo infinito1 no condizione]:

 my $b;
 for ( $b = 0 ;  ; $b++ )
 {
    print "iterazione numero $b\n";
 }
 print "Ultima iterazione numero $b\n";

Sorpresi? se non c'è una condizione che ferma il ciclo (o se questa non si verifica mai!) il ciclo continua indefinitamente!

Vediamo ora che cosa succede se togliamo l'incremento (CTRL+C per fermare) [ciclo infinito2 no incremento]:

 my $max_valore = 10;
 
 my $b;
 for ( $b = 0 ; $b < $max_valore ; )
 {
    print "iterazione numero $b\n";
 }
 print "b=$b\n";

Sorpresi? se non c'è un incremento, la condizione che ferma il ciclo sarà sempre vera; quindi, il ciclo continua indefinitamente!

NOTA: Continua indefinitamente perché, nel blocco, $b non viene alterata e quindi il suo valore rimane costante. Pertanto la condizione

$b < $max_valore 

è sempre vera.

vediamo ora che cosa succede se togliamo l'inizio [ciclo finito senza inizio]:

 my $max_valore = 10;
 
 my $b;
 for ( ; $b < $max_valore ; $b++ )
 {
    print "iterazione numero $b\n";
 }
 print "b=$b\n";

che produrrà:

iterazione numero   
iterazione numero 1 
iterazione numero 2 
iterazione numero 3 
iterazione numero 4 
iterazione numero 5 
iterazione numero 6 
iterazione numero 7 
iterazione numero 8 
iterazione numero 9 
b=10

Come si vede, mancando un valore iniziale a $b è stato messo il valore undef che nel caso della condizione viene posto a uguale al valore 0 mentre nel caso della stringa viene posto uguale al valore "". Dopo la prima iterazione dal valore undef diventa 1 per effetto della chiamata $b++ e poi si incrementa.

While e Until modifica

Il ciclo while è come il ciclo for con la sola condizione. Le istruzioni nel blocco vengono eseguite fino a quando la condizione è vera. Il ciclo until è come il ciclo while ma vengono eseguite le istruzioni se la condizione NON è verificata.


 while ( <condizione> )   
 {
    ... istruzioni ...
 }

 until ( <condizione> )   
 {
    ... istruzioni ...
 }

Vediamo come ottenere i cicli precedenti con while e until: [ciclo finito]

 my $max_valore = 10;
 
 my $b=0;
 while ( $b < $max_valore )
 {
    print "iterazione numero $b\n";
    $b++ ;
 }
 print "b=$b\n";


 my $max_valore = 10;
 
 my $b=0;
 until ( $b > $max_valore - 1 )
 {
    print "iterazione numero $b\n";
    $b++ ;
 }
 print "b=$b\n";

[ciclo infinito1 no condizione]: la condizione è necessaria quindi questo caso non è possibile.

[ciclo infinito2 no incremento] (CTRL + C per terminare):

 my $max_valore = 10;
 
 my $b=0;
 while ( $b < $max_valore )
 {
    print "iterazione numero $b\n";
 }
 print "b=$b\n";


 my $max_valore = 10;
 
 my $b=0;
 until ( $b > $max_valore - 1 )
 {
    print "iterazione numero $b\n";
 }
 print "b=$b\n";

[ciclo finito senza inizio ] :

 my $max_valore = 10;
 
 my $b;
 while ( $b < $max_valore )
 {
    print "iterazione numero $b\n";
    $b++ ;
 }
 print "b=$b\n";


 my $max_valore = 10;
 
 my $b;
 until ( $b > $max_valore - 1 )
 {
    print "iterazione numero $b\n";
    $b++ ;
 }
 print "b=$b\n";

Do ... While e Do ... Until modifica

Questo costrutto è nella realtà una chiamata a funzione. Apparentemente assomiglia al costrutto sintattico di altri linguaggi ma perde (come ogni chiamata a funzione) la possibilità di usare i modificatori di ciclo. È un costrutto usato se occorre fare almeno una iterazione e poi un controllo. Si basa sul principio di while e until con l'unica differenza che la condizione viene verificata alla fine del blocco di istruzioni , pertanto almeno una volta le istruzioni vengono eseguite.

 do
 {
    ... istruzioni ...
 }
 while ( <condizione> );

 do
 {
    ... istruzioni ...
 }
 until ( <condizione> );

NOTA:avete notato il ; alla fine ?

Riportiamo gli esempi con questo costrutto: [ciclo finito]

 my $max_valore = 10;
 
 my $b=0;
 
 do
 {
    print "iterazione numero $b\n";
    $b++ ;
 } while ( $b < $max_valore );
 
 print "b=$b\n";


 my $max_valore = 10;
 
 my $b=0;
 
 do
 {
    print "iterazione numero $b\n";
    $b++ ;
 } until ( $b > $max_valore - 1 );
  
 print "b=$b\n";

[ciclo infinito1 no condizione]: la condizione è necessaria quindi questo caso non è possibile.

[ciclo infinito2 no incremento] (CTRL + C per terminare):

 my $max_valore = 10;
 
 my $b=0;
 
 do
 {
    print "iterazione numero $b\n";
 } while ( $b < $max_valore );
  
 print "b=$b\n";


 my $max_valore = 10;
 
 my $b=0;
 do
 {
    print "iterazione numero $b\n";
 } until ( $b > $max_valore - 1 );
 
 print "b=$b\n";

[ciclo finito senza inizio ] :

 my $max_valore = 10;
 
 my $b;
 do
 {
    print "iterazione numero $b\n";
    $b++ ;
 } while ( $b < $max_valore );
 
 print "b=$b\n";


 my $max_valore = 10;
 
 my $b;
 
 do
 {
    print "iterazione numero $b\n";
    $b++ ;
 } until ( $b > $max_valore - 1 );
 print "b=$b\n";

È opportuno precisare che modificando opportunamente i valori iniziali , è possibile ottenere che venga eseguito almeno una volta il ciclo utilizzando while o until Vediamo questo esempio: [do ... while ]

 my $anni = 15;

 do
 {
    print "hai avuto anche $anni\n";
    $anni-- ;
 } while ( $anni > 0 );

che produce :

hai avuto anche 15
hai avuto anche 14
hai avuto anche 13
hai avuto anche 12
hai avuto anche 11
hai avuto anche 10
hai avuto anche 9
hai avuto anche 8
hai avuto anche 7
hai avuto anche 6
hai avuto anche 5
hai avuto anche 4
hai avuto anche 3
hai avuto anche 2
hai avuto anche 1
hai avuto anche 0

NOTA:se $anni = 0 viene almeno scritta una riga : "hai avuto anche 0" [do ... until ]

 my $anni = 15;

 do
 {
    print "hai avuto anche $anni\n";
    $anni-- ;
 } until ( $anni < 0 );

[while]

 my $anni = 15;
 
 while ( $anni >= 0 )
 {
    print "hai avuto anche $anni \n";
    $anni-- ;
 }

[until]

 my $anni = 15;
 
 until ( $anni <= 0 )
 {
    print "hai avuto anche $anni \n";
    $anni-- ;
 }

Foreach modifica

Questa istruzione consente di "scandire" una lista (array).

 foreach <variabile> ( <lista> )
 {
     ... istruzioni ...
 }

Vediamo ora come è possibile creare il [ciclo finito]:

 my $max_valore = 10;
 
 my $b;
 
 foreach $b ( 0 .. ($max_valore - 1) )
 {
    print "iterazione numero $b\n";
 }
 print "b=$b\n";

che produrrà :

iterazione numero 0
iterazione numero 1
iterazione numero 2
iterazione numero 3
iterazione numero 4
iterazione numero 5
iterazione numero 6
iterazione numero 7
iterazione numero 8
iterazione numero 9
b=9

NOTA: $b non è stato incrementato ma assume il valore di volta in volta contenuto in lista.Infatti non ha valore 10 ma 9 !

While , Until , Foreach e Continue modifica

Questo costrutto è utile quando "al termine di ogni iterazione" occorre compiere una serie di incrementi oppure quando si vuole "evidenziare" l'incremento:

 while ( <condizione> )   
 {
    # Nota Redo passa qui
    ... istruzioni ...
 }
 continue
 {
    # Nota Next passa qui
    ... istruzioni ...
 }
 # Nota Last passa qui (termina fuori)

 until ( <condizione> )   
 {
    # Nota Redo passa qui
    ... istruzioni ...
 }
 continue
 {
    # Nota Next passa qui
    ... istruzioni ...
 }
 # Nota Last passa qui (termina fuori)

 foreach ( <lista> )   
 {
    # Nota Redo passa qui
    ... istruzioni ...
 }
 continue
 {
    # Nota Next passa qui
    ... istruzioni ...
 }
 # Nota Last passa qui (termina fuori)

È un modo per riproporre lo spazio per l'incremento del ciclo for.

Esempio:

 my $b = 15;   
 my $salto = 17;

 while ( $b < 20 )                                
 {                                                
     if ( $salto == $b ) { next; }
                                                 
     print " etichetta tre (b=$b).\n"; 
 }                                                
 continue                                         
 {                                                
    $b++;                                        
 }

che produce :

etichetta tre (b=15)
etichetta tre (b=16)
etichetta tre (b=18)                                     
etichetta tre (b=19)                                     
                                                

Esempio:

 my $b = 15;                           
 my $salto = 17;                       
                                       
 foreach $b ( 15 .. 20 )               
 {                                     
     if ( $salto == $b ) { next; }     
                                       
     print "tratto b=$b\n"; 
 }                                     
 continue                              
 {                                     
     print "continue b=$b\n";          
 }

che produce:

tratto b=15
continue b=15        
tratto b=16
continue b=16        
continue b=17        
tratto b=18
continue b=18        
tratto b=19
continue b=19        
tratto b=20
continue b=20