Perl/Cicli
Wikibooks, manuali e libri di testo liberi.
Indice |
[modifica] I cicli
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.
[modifica] For
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.
[modifica] While e Until
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";
[modifica] Do ... While e Do ... Until
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-- ; }
[modifica] Foreach
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 !
[modifica] While , Until , Foreach e Continue
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