« Tcl: Controllo del flusso: comando switchAppunti di Tcl/TkTcl: Iterazioni: comando for »

Tcl

Iterazioni

comando while

Senza la possibilità di ripetere una sezione di codice con differenti valori delle variabili, non sarebbe possibile descrivere moltissimi algoritmi utili. Quindi anche Tcl deve per forza includere dei comandi di ciclo (loop in inglese).

Uno di questi è while(n) che ha una sintassi molto semplice:

while test body

while(n) interpreta il parametro test tramite expr(n), proprio come fa if(n).

La semantica di while(n) descritta a parole: dapprima viene valutata l'espressione test. Se questa si valuta come vera, viene eseguito il codice body chiamando ricorsivamente l'interprete. Quando l'esecuzione del corpo è terminata, viene di nuovo valutata l'espressione test e il processo continua finché test non si valuta a false o nel body viene eseguito un comando break (vedi seguito).

Per esempio il ciclo seguente estrae le cifre decimali di un numero in ordine inverso:

% set x 1948
1948
% while {$x} {
  puts [expr $x%10]
  set x [expr $x/10]
}
8
4
9
1

Sostituendo la costante 10 con un altro valore, diciamolo B, si ottiene la conversione in base B del numero x. Questo è il metodo delle divisioni successive. L'unica difficoltà è che purtroppo i resti vengono fuori in ordine inverso. Concatenando la cifra ottenuta come resto con la stringa dei resti ottenuta finora risolviamo il problema:

% set x 1948
1948
% set y "" ;# or set y {}
% while {$x} {
  set y [expr $x%8]$y
  set x [expr $x/8]
}
% puts $y
3634

Questo esempio mostra che 1948 in ottale si scrive come 3634. Notate che la condizione avrebbe anche potuto scriversi in forma booleana:

...
while {$x!=0} {
...

Questo codice funziona correttamente per ogni valore di x, escluso lo zero, per cui y rimane la stringa vuota. Questo errore può essere aggiustato aggiungendo una istruzione if(n) nel punto mostrato di seguito:

...
}
if {$y==""} {set y 0}
puts $y

Sarebbe un grave errore se il test del while(n), sia che venga scritto in forma booleana o meno, non fosse racchiuso tra {}:

...
while $x {
...
o fosse racchiuso tra "":
...
while "$x" {
...

In entrambi i casi accade che il parametro $x viene valutato durante la fase di sostituzione, prima dell'esecuzione del comando while(n). L'argomento passato a while(n) diviene l'espressione costante corrispondente al valore di x. Se questo è 0, il ciclo while non viene eseguito nemmeno una volta e il programma termina correttamente. Ma se è un numero diverso da 0, allora accadrà che la condizione del while(n) è sempre vera. Il while(n) allora diventa un ciclo infinito e il programma non termina mai, e da un certo punto in poi continuerà ad emettere sempre degli zeri come output.

Il comando while ritorna sempre una stringa vuota.

« Tcl: Controllo del flusso: comando switchAppunti di Tcl/TkTcl: Iterazioni: comando for »