Perl/Cicli
I cicli
modificaI 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
modificaIl 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
modificaIl 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
modificaQuesto 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
modificaQuesta 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
modificaQuesto 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