Cicli.


L'esempio 2 ha un 'bug', cioè un errore di programmazione che causa un malfunzionamento: se l'utente lascia vuoto il campo di input e preme OK, la funzione ciao() emette un messaggio Ciao, o, peggio ancora, se preme Annulla, Ciao, null, che non ha molto senso.

Bisogna 'costringere' l'utente o a rinunciare o ad immettere qualcosa di sensato nel campo di input del riquadro generato da prompt() prima che possa venir emesso il messaggio di saluto prodotto da alert().

La seguente pagina tenta di risolvere il malfunzionamento.

Il sorgente è il seguente

<!DOCTYPE html>
<html lang="it">
<head> 
  <title>Esempio 3</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <script">
    var nome = "";
    function ciao()
      {
        var va_bene = false;
        while (!va_bene)
          {
            nome = prompt("Come ti chiami?",nome);
            if (nome==null)
              {
                nome = "";
                return;
              }
            else
              { 
                var lunghezza = nome.length;
                va_bene = lunghezza>0;
                if (va_bene)
                  for (var i=0; i<lunghezza;i++)
                    {
                      var carattere=nome.charAt(i);
                      if((carattere<'A')||(carattere>'z'))
                        {
                          va_bene = false;
                          break;
                        }
                      if((carattere >'Z')&&(carattere <'a'))
                        {
                          va_bene = false;
                          break;
                        }
                    }
              } 
            if (!va_bene) 
              alert("Scrivere bene il nome e premere OK");
          }
        alert("Ciao, "+nome);}
  </script>
</head>

<body style="background-color:cyan">
<form name="frm" id="frm" 
  style="position:relative; width:40%; left:30%; top:100px; 
   background-color:azure; color:blue; 
   border-style:solid; border-color:blue; text-align:center">
<h2>Saluto</h2>
<p>
<input type="button" value = " SALUTA " onclick = "ciao()" />
</p>
</form>
</body>
</html>


In questa versione della funzione ciao(), si ripete la richiesta di input fino a che l'utente possa confermare solo se ha immesso un dato significativo

Questa ripetizione è prodotta dall'istruzione while(!va_bene) che significa:"Fintanto che va_bene è falso, ripetere le seguenti istruzioni".

Le istruzioni da ripetere sono quelle contenute nel blocco delimitato da parentesi graffa che segue la clausola while.

L'istruzione finale alert("Ciao, "+nome) verrà eseguita solo quando cesseranno le iterazioni.

Il blocco viene eseguito almeno una volta, in quanto la variabile va_bene è iniziata a false. Il punto esclamativo davanti a va_bene rappresenta l'operatore di negazione logica.

Nel blocco, l'istruzione nome = prompt("Come ti chiami?",nome) emette il riquadro della domanda. Se l'utente chiude il riquadro premendo Annulla, nome diventa una stringa vuota, di lunghezza zero.

La variabile lunghezza assume il valore corrispondente al numero di caratteri della stringa nome. Questa lunghezza è calcolata dalla proprietà length di un oggetto String generato a partire dalla stringa nome.

Se lunghezza è maggiore di zero, si esaminano i caratteri delle stringa nome per vedere se essa contiene dei numeri, non ammessi nel nome di una persona.

Per esaminare i caratteri bisogna ripetere il controllo di un carattere un numero di volte corrispondente alla lunghezza della stringa. Si potrebbe usare anche in questo caso l'iteratore while ma in situazioni del genere risulta più comoda una sua variante introdotta dalla clausola for.

for è seguito da parentesi tonde contenenti tre specificazioni separate da punto e virgola:

  1. l'assegnazione di un valore iniziale ad una variabile di controllo; nell'esempio i=0;
  2. la condizione che deve essere vera perché si abbia la ripetizione; nell'esempio i<lunghezza;
  3. la variazione della variabile di controllo: nell'esempio i++
    (l'istruzione postfissa ++ aumenta di un'unita la variabile cui si riferisce);

Quindi all'inizio del ciclo i vale 0, il suo valore aumenta di un'unità ad ogni iterazione e le iterazioni cessano quando i diventa uguale a lunghezza.

Ad ogni passo del ciclo, si rileva lo i-esimo carattere della stringa nome. Questa rilevazione è fatta usando il metodo charAt() dell'oggetto String che produce appunto lo i-esimo carattere di una stringa.

Se questo carattere non è una lettera allora la stringa non è valida e va_bene diventa false. Se va_bene è false allora è inutile esaminare i caratteri seguenti e si interrompe l'iterazione con l'istruzione break.

Per controllare se un carattere è una lettera maiuscola o minuscola, lo si confronta con la minore delle lettere, cioè 'A' e con la maggiore, cioè 'z'. Se è minore di 'A' o maggiore di 'z', allora non è una lettera.

Ma il gruppo delle lettere maiuscole non è contiguo al gruppo delle lettere minuscole: tra questi due gruppi sono interposti altri caratteri non accettabili in un nome. Chi usa Windows può controllare in Mappa caratteri. Bisogna quindi scartare anche i caratteri compresi tra 'Z' e 'a'.

Riassumendo e completando:

Le istruzioni di iterazione con controllo iniziale sono introdotte dalla clausola while (condizione vera) {...}.

Il ciclo viene eseguito almeno una volta solo se la condizione di controllo è inizialmente vera.

Nel blocco un'istruzione deve falsificare la condizione, altrimenti il ciclo si ripete senza fine.

Le istruzioni di iterazione con con contatore si usano quando il numero delle iterazioni è prestabilito.

Queste istruzioni sono introdotte dalla clausola for (inizializzazione della variabile di controllo; controllo; variazione delle variabile di controllo) {...}.

Il ciclo viene eseguito fintanto che il controllo risulta vero.

Sono possibili anche istruzioni di iterazione con controllo finale. Queste sono introdotte dalla clausola do {...} while (condizione vera).

In questo caso il ciclo viene eseguito comunque almeno una volta.

Nel blocco un'istruzione deve falsificare la condizione, altrimenti il ciclo si ripete senza fine.

Un ciclo può essere interrotto forzatamente prima della conclusione gestita dalla variabile di controllo usando l'istruzione break.
Con gli oggetti di tipo String si possono usare la proprietà length che ne registra la lunghezza e il metodo charAt(valore intero) che ne individua un carattere. La posizione di un carattere varia da 0 (il primo) a length-1 (l'ultimo).
Le condizioni di verità possono essere combinate in modo anche molto complesso usando gli operatori logici di disgiunzione (or) e congiunzione (and). Può essere un esercizio utile provare a sostituire con una sola istruzione le due istruzioni if nel controllo della validità dei caratteri.

 

operatori logici (booleani)
operatore operazione esempio
! negazione a = !b
&& congiunzione c = a && b
|| disgiunzione c = a || b