regola carattere

programmare

selezione

strutture di controllo

In un qualunque programma, si dispone di due tipi di strutture di controllo:

selezione
la scelta tra due diversi percorsi.
iterazione
la ripetizione ciclica di istruzoni.

strutture di controllo selettive

struttura if

La struttura di controllo if (in italiano: se), dapprima verifica una condizione e, soltanto se questa è verificata, esegue l'istruzione (o il blocco di istruzioni) in essa contenuta.

La sua sintassi in JavaScript sarebbe if (condizione) istruzione, ma volendo eseguire più istruzioni le si dovrebbero riunire in blocco di istruzioni.

Per evitare di dimenticarsi di aggiungere le parentesi graffe quando si aggiungono istruzioni, conviene usare sempre la seguente sintassi, anche nel caso di una sola istruzione:

if (condizione) {
	istruzione 1;
	istruzione 2;
	...
	istruzione n;
}

Dicendo verifica una condizione, intendiamo: controlla che l'espressione condizione, restituisca il valore true (vero).

Visto che si è parlato prima della funzione isNaN, proviamo ad eseguire un blocco di istruzioni verificando i risultati di IsNaN

var str1 = 'testo senza numeri';
var num1 = parseInt(str1); // parseInt restituisce NaN che viene assegnato alla variabile num1
var seNaN1 = isNaN(num1); // isNaN restituisce true che viene assegnato alla variabile seNaN1
// struttura di controllo if con condizione verificata
if (seNaN1) { // la condizione è verificata quindi si esegue il blocco di istruzioni
	document.write('<p>str1: ' + str1 + '</p>');
	document.write('<p>num1: ' + num1 + '</p>');
	document.write('<p>seNaN1: ' + seNaN1 + '</p>');
	window.alert('Attenzione!:\n\'' + str1 + '\' non è un numero.')
}

var str2 = '123';
var num2 = parseInt(str2); // parseInt restituisce il num2 123 che viene assegnato alla variabile num2
var seNaN2 = isNaN(num2); // isNaN restituisce false che viene assegnato alla variabile seNaN2
// struttura di controllo if con condizione NON verificata
if (seNaN2) { // la condizione NON è verificata quindi NON si esegue il blocco di istruzioni
	document.write('<p>str2: ' + str2 + '</p>');
	document.write('<p>num2: ' + num2 + '</p>');
	document.write('<p>seNaN2: ' + seNaN2 + '</p>');
	window.alert('Attenzione!:\n\'' + str2 + '\' non è un numero.')
}

document.write('<p>fatto</p>');

Che succede?

La varibile str1, non contiene numeri, quindi parserInt, non trovando numeri, restituisce il valore speciale NaN. Esaminano questo valore con la funzione isNaN, si ottiene true.

La struttura if, verificando la condizione, la trova vera (true) quindi esegue il blocco di istruzioni.

Nel secondo caso, la conversione in numero della stringa str2, va a buon fine, quindi isNaN restituisce false e, non essendo verificata la condizione, la struttura if non esegue le istruzioni ed il programma esce dall'if e trova il document.write che scrive fatto nella pagina.

apri l'esercitazioneapri l'esercitazione in formato pdf

gli operatori di confrontofreccia per tornare ad inizio pagina

Molto spesso, le condizioni verificate dalle strutture di controllo selezione ed iterazione, sono il risultato di un operazione di confronto.

Queste operazioni restituiscono sempre un valore logico (true o false).

Ad esempio 1 < 2 restituirà true e 10 > 3 restituirà false,

Per eseguire le operazioni di confronto si dispone di questi operatori:

operatori di confronto
operatoresignificato
>maggiore
<minore
>=maggiore o uguale
<=minore o uguale
==uguale
!=diverso

Fare attenzione al fatto che l'operatore == opera un confronto e restituisce true o false, da con confondersi con = che è l'operatore assegnazione.

Forse non è inutile precisare che, rispetto ad un dato numero, un qualunque altro numero può essere o minore o uguale o maggiore. Rispetto al numero 5, per esempio, tutti quelli da -∞ a 5 (5 escluso) sono minori, il 5 è uguale e quelli da 5 (5 escluso) a +∞ sono maggiori.

Ne deriva che, sempre rispetto ad un numero dato, un altro qualunque numero,

e così via.

esempi di uso della struttura iffreccia per tornare ad inizio pagina

Altri esempi di uso della struttura di controllo if potrebbero essere:

  1. una pagina che avverte se non si ha diritto al voto.
  2. un programma che stabilsce se una password è sbagliata.
  3. un titolo che viene scritto solo se confermato dall'utente

if (esempio 1)freccia per tornare ad inizio pagina

In questo esempio, prima chiediamo all'utente la sua età e, se minorene lo avvertiamo che non ha diritto a votare.

var eta = window.prompt('immettere la propria età','');
eta = parseInt(eta);
if (eta < 18) {
	window.alert('In quanto minorenne non hai diritto al voto.');
}

// alernativa più efficiente:
// var eta = parseInt(window.prompt('immettere la propria età',''));

apri l'esercitazioneapri l'esercitazione in formato pdf

if (esempio 2)freccia per tornare ad inizio pagina

In questo esempio chiediamo all'utente di indovinare una password prestabilita (JavaScript) e lo avvertiamo nel caso in cui abbia sbagiato:

var psw = window.prompt('indovinare la password','');
if (psw != 'JavaScript') {
	window.alert('password errata!');
}

apri l'esercitazioneapri l'esercitazione in formato pdf

if (esempio 3)freccia per tornare ad inizio pagina

In questo esempio chiediamo conferma all'utente di scrivere il titolo nella pagina e lo si scriverà solo in caso affermativo:

var conf = window.confirm('scrivere il titolo?');
if (conf) {
	document.write('<h1>titolo condizionato</h1>');
}

apri l'esercitazioneapri l'esercitazione in formato pdf

if-elsefreccia per tornare ad inizio pagina

La struttura di controllo if, esegue un gruppo di istruzioni se una condizione è verificata e in caso contrario non esegue nessuna istruzione.

Volendo sempre eseguire un gruppo di istruzioni se la condizione è verificata, ma anche esguirne un secondo gruppo in caso contrario, bisogna usare la struttura di controllo if-else.

È sufficiente aggiungere alla struttura if, il caso else (in italiano: altrimenti), secondo la seguente sintassi:

if (condizione) {
	istruzioni se condizione vera;
} else {
	istruzioni se condizione falsa;
}

Portiamo ad esempio uno script che chieda all'utente di indovinare chi sia l'autore della frase "Il perder tempo a chi più sà più spiace", quindi scriva nella pagina se la risposta è esatta o errata.

Questo è lo script:

var risp = window.prompt('chi disse:\n"Il perder tempo a chi più sà più spiace"?','');
if (risp=='Dante') {
	document.write('<h1>esatto!</h1>');
	document.write('<p>&Egrave; una citazione del sommo poeta.</p>');
} else {
	document.write('<h1>sbagliato!</h1>');
	document.write('<p>Puoi comunque riprovare.</p>');
}
}

apri l'esercitazioneapri l'esercitazione in formato pdf

esempi di uso della struttura if-else

Altri esempi dell'uso della struttura di controllo if-else potrebbero essere:

  1. una pagina come quella sopra, ma che "risponda" sia a chi non ha diritto di voto, sia ai maggiorenni.
  2. uno script che distingua tra pari e dispari esaminando un numero immesso dall'utente
  3. una pagina che faccia uso delle tre finestre di dialogo.

if-else (esempio 1)freccia per tornare ad inizio pagina

In questo esempio, come in quello precedente, viene chiesto all'utente di immettere la propria età, quindi, se minorenne si visualizza un messaggio di avvertimento, ed in più, si scrive un messaggio nella pagina se maggiorenne.

var eta = window.prompt('immettere la propria età','');
eta = parseInt(eta);
if (eta < 18) {
	window.alert('In quanto minorenne non hai diritto al voto.');
} else {
	document.write('<h1>voto on-line</h1>');
	document.write('<p>visto che hai ' + eta + ' anni, hai diritto di voto.</p>');
}

// alernativa più efficiente:
// var eta = parseInt(window.prompt('immettere la propria età',''));

note

Se l'età non è minore di 18 è necessariamente maggiore o uguale. Sarebbe stato quindi equivalente verifica se eta >= 18 e ovviamente invertire le istruzioni da eseguire se vero e se falso.

Così:

if (eta >= 18) {
	document.write('<h1>voto on-line</h1>');
	document.write('<p>visto che hai ' + eta + ' anni, hai diritto di voto.</p>');
} else {
	window.alert('In quanto minorenne non hai diritto al voto.');
}

apri l'esercitazioneapri l'esercitazione in formato pdf

if-else (esempio 2)freccia per tornare ad inizio pagina

Per determinare se un numero immesso dall'utente sia pari o dispari, ci si avvale dell'operatore % il quale fornisce il resto della divisione intera (8 % 2 restituisce 0 perché 8 diviso 2 fa 4 con il resto di 0; invece 7 % 2 restituisce 1 perché 7 diviso 2 fa 3 con il resto di 1). Dividendo il numero per 2, controlleremo il resto: se 0, allora il numero è pari, altrimenti, è dispari.

var num = window.prompt('immettere un numero intero:','');
num = parseInt(num);
var resto = num % 2;
if (resto == 0) {
	document.write('<p>Il numero ' + num + ' &egrave; <b>pari</b></p>');
} else {
	document.write('<p>Il numero ' + num + ' &egrave; <b>dispari</b></p>');
}

// alernativa più efficiente:
// var num = parseInt(window.prompt('immettere un numero intero:',''));
// if (num % 2 == 0) {

apri l'esercitazioneapri l'esercitazione in formato pdf

if-else (esempio 3)freccia per tornare ad inizio pagina

Quello che segue un è banale esempio di script che contempla tutte le finestre di dialogo,

var nome = window.prompt('Inserire il proprio nome','qui');
var conferma = window.confirm('Sei sicuro di chiamarti ' + nome + '?');
if (conferma) {
	window.alert('Benvenuto/a ' + nome + '!!!');
} else {
	window.alert('Non sai neanche come ti chiami?');
}

// alernativa più efficiente:
// if (window.confirm('Sei sicuro di chiamarti ' + nome + '?')) {

apri l'esercitazioneapri l'esercitazione in formato pdf

strutture di controllo if nidificatefreccia per tornare ad inizio pagina

In questi ultimi esempi, non avendo considerato tutte le risposte che l'utente può dare, potremmo avere diversi problemi:

Nell'esempio 1 (if-else), non abbiamo considerato che l'utente, invece che immettere un numero possa:

Infatti:

Le soluzioni sono due:

  1. verificare prima che l'utente non abbia premuto annulla, quindi controllare che non abbia prenuto ok senza immettere nulla e soltanto se non vere queste due ipotesi (l'utente ha scritto qualcosa), provare a convertire la stringa iin numero e controllare se la conversione sia andata a buon fine o no; quindi, solo nel caso si abbia un numero, confrontarlo con il valore 18 per stabilire se maggiorenne o meno.
  2. provare subito a convertire la risposta in numero con parseInt, perché questa funzione restituirà il valore NaN in tutti tre i casi di errore (ne' null, né stringa nulla, né una stringa alfabetica sono convertibili in numero). Quindi verificare la maggiore età solo se la conversione in numero è andata a buon fine.

In entrambi i casi, bisognerà inserire delle strutture if dentro ad altre strutture if, ovvero nidificare le strutture di controllo.

NB:

Non vale soltanto le strutture if , si possono nidificare tutte le strutture di controllo.

if nidificati (esempio 1)freccia per tornare ad inizio pagina

Proviamo la prima soluzione:

diagramma di flusso

Nel diagramma di flusso, i blocchi evidenziati corrispondono alle strutture if.

Come si nota, verificando che l'iutente abbia dato uno dei tre tipi di risposta non valida, procediamo per esclusione: soltanto alla fine, una volta esclusi tutti i casi non validi, ossia tutte le condizioni non sono verificate, essendo sicuri di avere un numero, procediamo a controllare la maggiore età.

Lo script pertanto sarà:

var eta = window.prompt('immettere la propria età','');
if (eta == null) {
	window.alert('errore:\nrisposta non valida');
} else {
	if (eta == '') {
		window.alert('errore:\nrisposta non valida');
	} else {
		eta = parseInt(eta);
		if (isNaN(eta)) {
			window.alert('errore:\nrisposta non valida');
		} else {
			if (eta < 18) {
				window.alert('In quanto minorenne non hai diritto al voto.');
			} else {
				document.write('<h1>voto on-line</h1>');
				document.write('<p>visto che hai ' + eta + ' anni, hai diritto di voto.</p>');
			}
		}
	}
}

apri l'esercitazioneapri l'esercitazione in formato pdf

if nidificati (esempio 2)freccia per tornare ad inizio pagina

Ecco invece la seconda soluzione::

diagramma di flusso

Come detto, questa soluzione, si avvantaggia del fatto che, sottoponendo all'esame della funzione parseInt la risposta dell'utente, essa restituirà NaN sia se l'utente ha premuto il tasto annulla (parseInt(null) → NaN), sia nel caso l'utente abbia premuto il tasto ok senza scrivere nulla (parseInt('') → NaN), sia nel caso l'utente non abbia immesso un numero valido (parseInt('stringa alfabetica') → NaN).

Lo script sarà:

var eta = window.prompt('immettere la propria età','');
eta = parseInt(eta);
if (isNaN(eta)) {
	window.alert('errore:\nrisposta non valida');
} else {
	if (eta < 18) {
		window.alert('In quanto minorenne non hai diritto al voto.');
	} else {
		document.write('<h1>voto on-line</h1>');
		document.write('<p>visto che hai ' + eta + ' anni, hai diritto di voto.</p>');
	}
}

// alernativa più efficiente:
// var eta = parseInt(window.prompt('immettere la propria età',''));

apri l'esercitazioneapri l'esercitazione in formato pdf

operatori logicifreccia per tornare ad inizio pagina

Abbiamo accennato all'algebra di Boole parlando dei dati di tipo logico (o booleano) che possono asseumere i valori vero o falso (true o false).

Questa algebra definisce gli operatori logici: uno strumento che semplificherà molto i nostri programmi, consentendoci per esempio di riunire la verifica di diverse condizioni in un'unica espressione.

operatori logici
operatoreoperazione
! not (negazione logica)
&& and (congiunzione logica)
¦¦ or (disgiunzione logica)

not

L'operatore not, ha un solo operando: restituisce true se l'operando è false e false se l'operatore è true (o non booleano).

and

L'operatore and, restituisce true solo se i suoi due operandi sono entrambi true (false in caso contrario).

or

L'operatore or, restituisce true, quando almeno uno dei sui operandi è true (quindi false solo se entrambi false).

Queste sono lo corrispondenti tabelle di verita:

not
A !A
V F
F V
and
A B A && B
V V V
V F F
F V F
F F F
or
A B A|| B
V V V
V F V
F V V
F F F

operatore logice notfreccia per tornare ad inizio pagina

Se volessimo uno script che scriva nella pagina un numero digitato dall'utente, prima di scriverlo, bisognerebbe controllare che l'utente abbia immesso un numero valido, ovvero che la funzione parseInt non restituisca NaN.

La funzione isNaN, restituisce true se l'argomento è NaN, ma a noi interessa il caso opposto: vogliano scrivere la risposta se non è NaN (not isNaN).

var num = parseInt(window.prompt('immettere un numero da scrivere nella pagina',''));
if (!isNaN(num)) {
	document.write('<p>numero immesso: <b>' + num + '</b></p>');
} else {
	window.alert('errore:\nnumero non valido');
}

apri l'esercitazioneapri l'esercitazione in formato pdf

operatore logico andfreccia per tornare ad inizio pagina

Ora vogliamo uno script che chieda all'utente il suo voto all'esame di informatica, quindi lo scriva nella pagina.

Prima bisogna controllare che l'utente abbia immesso un numero valido, ma vogliamo anche che il numero immesso sia un voto in trentesimi valido: compreso tra 1 e 30.

Bisogna cioè verificare altre due condizoni:

Senza operatori logici dovremmo usare strutture di controllo if nidificate:

diagramma di flusso

in JavaScript:

var voto = parseInt(window.prompt('immettere il voto dell\'esame di informatica',''));
if (!isNaN(voto)) {
	if (voto > 0) {
		if (voto <=30) {
			document.write('<p>voto in informatica: ' + voto + '<small>/30</small></p>');
		} else {
			window.alert('errore:\nvoto non valido');
		}
	} else {
		window.alert('errore:\nvoto non valido');
	}
} else {
	window.alert('errore:\nnumero non valido');
}

Perché il voto sia valido, le condizioni voto > 0 e voto <= 30, devono essere entrame verificate (true): il numero deve essere oltre il minimo e anche (AND) entro il massimo

È con l'operatore logico AND (&&) che avremo true quando entrambi gli operandi siano true.

Allora, ci basterà verificare un'unica condizione: voto > 0 && voto <= 30:

diagramma di flusso

In JavaScript:

var voto = parseInt(window.prompt('immettere il voto dell\'esame di informatica',''));
if (!isNaN(voto)) {
	if (voto > 0 && voto <= 30) {
		document.write('<p>voto in informatica: ' + voto + '<small>/30</small></p>');
	} else {
		window.alert('errore:\nvoto non valido');
	}
} else {
	window.alert('errore:\nnumero non valido');
}

Si capisce che, volendo, protremmo anche verificare tutte tre le condizioni usando una espressione soltanto:

diagramma di flusso

Ed ecco lo script:

var voto = parseInt(window.prompt('immettere il voto dell\'esame di informatica',''));
if (!isNaN(voto) && voto > 0 && voto <= 30) {
	document.write('<p>voto in informatica: ' + voto + '<small>/30</small></p>');
} else {
	window.alert('errore:\nvoto non valido');
}

apri l'esercitazioneapri l'esercitazione in formato pdf

Attenzione all'ordine perché non è casuale:

  1. Prima si verifica la condizione: !isNaN(voto).
  2. Se questa non è verificata (false) la seconda non viene verificata e l'AND restituisce false.
    Perché? Visto che usando l'AND (&&) avremo true solo se entrambe true (!isNaN(voto) && voto > 0) se la prima è false non c'è bisogno di verificare l'altra.
  3. Solo se il primo operando dell'AND è true, si verifica il secondo: cioè il confronto voto > 0.
  4. Se questo non restituisce true, non si verifica il terzo per lo stesso motivo (ci sarebbe un secondo AND inutile: false && voto <= 30).
  5. Solo se il primo AND ha restituito true, allora si verifica la terza condizione (true && voto <= 30).
  6. Se anche questa è verificata l'espressione risulta true altrimenti false.

diagramma di flusso

operatore logico orfreccia per tornare ad inizio pagina

Chi l'ha detto?

Immaginiamo di proporre all'utente una citazione perché indovini chi l'abbia detta.

La disumanità del computer sta nel fatto che, una volta programmato e messo in funzione, si comporta in maniera perfettamente onesta.(Isaac Asimov)

L'utente che conoscesse la risposta potrebbe rispondere correttamente:

Per contemplare tutti i casi, senza gli operatori logici, il nostro script sarebbe costituito da ben sei strutture if, ma usando l'operatore OR (¦¦), basterà che una delle sei condizioni sia verificata (true) perché il risultato dell'unica espressione sia true.

L'operatore OR, come l'AND, valuta le condizioni a due a due da sinistra verso destra:

  1. Verifica la prima condizione: risp == 'Isaac Asimov' è true?.
  2. Se è verificata, non c'è bisogno di controllare le successive, perché visto che le condizione sono tutte tra OR, è sufficiente che sia true una, per restituire true.
  3. Se la prima condizione fosse false, si andrebbe avanti a valutare le successive condizioni fino alla prima verificata (true).
  4. Solo se tutte fossero false, l'espressione restituirà false.

In questo caso, quindi, l'ordine delle condizioni non è rilevante.

note

In questa pagina, porre la citazione nella finestra del prompt, sarebbe poco funzionale, quindi, prima dello script, inseriamo la citazione come paragrafo, così l'utente la legge nella pagina e nella finestra del prompt basterà chi l'ha detto?.

Per rendere più accattivante il quiz abbiamo lavorato un po' anche sul codice html della pagina, per dubbi, consultare la sezione html.

Questo è lo script:

var risp = window.prompt('chi l\'ha detto?','');
if (risp == 'Isaac Asimov' || risp == 'Isaac asimov' || risp == 'isaac Asimov' || risp == 'isaac asimov' || risp == 'Asimov' || risp == 'asimov') {
	document.write('<p align="right"><i>(Isaac Asimov)</i></p>');
	window.alert('risposta esatta!');
} else {
	document.write('<p align="right"><i>( ? )</i></p>');
	window.alert('risposta sbagliata\naggiorna la pagina per riprovare.');
}

apri l'esercitazioneapri l'esercitazione in formato pdf

alternativa all'orfreccia per tornare ad inizio pagina

È utile provare a costruire lo script senza usare l'operatore logico OR con la seguente strategia:

Questo è il diagramma di flusso:

diagramma di flusso

Questo il programma:

var risp = window.prompt('chi l\'ha detto?','');
var esatto = false;
if (risp == 'Isaac Asimov') esatto = true;
if (risp == 'Isaac asimov') esatto = true;
if (risp == 'isaac Asimov') esatto = true;
if (risp == 'isaac asimov') esatto = true;
if (risp == 'Asimov') esatto = true;
if (risp == 'asimov') esatto = true;
if (esatto) {
	document.write('<p align="right"><i>(Isaac Asimov)</i></p>');
	window.alert('risposta esatta!');
} else {
	document.write('<p align="right"><i>( ? )</i></p>');
	window.alert('risposta sbagliata\naggiorna la pagina per riprovare.');
}

apri l'esercitazioneapri l'esercitazione in formato pdf

note

Avendo una sola istruzione per le strutture if, abbiamo derogato alla regola generale che ci eravamo dati di usare sempre le parentesi graffe, ma in questo caso lo script migliora in leggibilità.