Un MANUALETTO di LINGUAGGIO PASCAL per il biennio

Parte B

 

 

8) LA STRUTTURA ITERATIVA FOR … DO …

 

La struttura

FOR i:= n1 TO n2 DO istruzione;

oppure:

FOR i:= n1 TO n2 DO

BEGIN

istruzione 1;

istruzione 2;

istruzione 3;

END;

 

ordina al computer di:

·         assegnare il valore n1 alla variabile i (NOTA);

·         eseguire l'istruzione che segue il DO (oppure, il blocco di istruz.  compreso fra il BEGIN che segue il DO e l' END successivo);

·         incrementare di una unità il valore di i;

·         eseguire nuovamente l'istruzione (o il blocco);

·         incrementare di un'altra unità i;

·         eseguire nuovamente l'istruzione (o il blocco);

·         .....

·         quando, a forza di incrementi di un'unità, la variabile i assume il valore n2, viene eseguita per l'ultima volta l'istruzione (o il blocco), poi si esce dal ciclo.

 

NOTA:

ho usato le lettera i per fissare le idee. Al posto di i si può mettere un qualunque identificatore di variabile integer.

La variabile i viene chiamata “variabile di controllo” del ciclo FOR, e dev’essere sempre di tipo integer.

 

 

UNA VARIANTE DELLA

FOR k:=1 to n DO

è la

FOR k:=n DOWNTO 1 DO …

Questa volta k viene fatto variare “a ritroso” (conto alla rovescia)

 

Esempi di programmi con l’uso della FOR … DO …:

 

program ti_saluto_10_volte;   uses crt;

var k: integer;

begin

clrscr;

for k:=1 to 10 do writeln (‘CIAO !’);

readln;

end.

 

ESEGUI IL PROGRAMMA

 

program ti_saluto_n_volte;   uses crt;

var k, n: integer; nome: string[20];

begin

clrscr;

writeln (‘Quante volte vuoi essere salutato?’);

readln (n);

for k:=1 to n do

begin

delay (10000);

writeln (‘CIAO !’);

end;

readln;

end.

 

ESEGUI IL PROGRAMMA

 

program tabellina_del_12;   uses crt;  (* qui avremo due FOR annidate una nell’altra! *)

var i, k: integer;

begin

clrscr;

for i:=1 to 12 do

begin

for k:=1 to 12 do write (i*k:4);

writeln;

end;

readln;

end.

 

ESEGUI IL PROGRAMMA

 

program disegno_un_triangolo_di_asterischi;   uses crt;

(* anche qui avremo due FOR annidate una nell’altra *)

var i, k, n: integer;

begin

clrscr;

for k:=1 to 10 do

begin

for i:=1 to k do write (‘*’);

writeln;

end;

readln;

end.

 

ESEGUI IL PROGRAMMA

 

program somma_dei_numeri_naturali_da_1_fino_a_n;    uses crt;

var k, n, somma: integer;

(*  in questo programma la variabile k funge da "CONTATORE"  e la variabile somma da "ACCUMULATORE" *)

begin

clrscr;

writeln ('Dammi un numero intero positivo n;');

writeln ('Ti scriverò la somma dei numeri interi da 1 fino ad n.');

readln (n);

somma:= 0;

for k:= 1 to n do

somma:=somma+k;

writeln;

write ('La somma che ti avevo promesso vale ', somma);

readln;

end.

 

ESEGUI IL PROGRAMMA

 

program massimo;      uses crt;

var a, n, k, max: integer;

(* questo programma riceve in input alcuni numeri e stabilisce quale è stato  il più grande fra i numeri introdotti.

La var. max svolge il ruolo di "MASSIMO PROVVISORIO";  il suo valore finale corrisponderà al massimo cercato *)

begin

clrscr; writeln ('Quanti numeri vuoi introdurre?'); readln (n);

writeln ('Dammi pure questi  ', n, '  numeri: ti dirò quale è il massimo');

max:=0;

for k:= 1 to n do

begin

readln (a);

if a>max then max:=a;

end;

writeln ('Massimo = ', max);

readln;

end.

 

ESEGUI IL PROGRAMMA

 

 

Esercizi:

 

Esercizio 4) 

Scrivi un programma che, letto da tastiera un numero intero positivo n, fornisca in output, su tre colonne:

i numeri interi da 1 fino a n;

i rispettivi quadrati;

le rispettive radici quadrate.

In altre parole, supponendo per fissare le idee n = 4, l'output desiderato è

 

NUMERO           QUADRATO         RADICE QUADRATA

1                             1                             1.00000

2                             4                             1.41421

3                             9                             1.73205

4                             16                           2.00000

 

Esercizio 5) 

Letto in input un intero positivo n, si vuole in output il valore della somma 1+1/2+1/3+1/4+ .... +1/n.

 

Esercizio 6) 

Letti in ingresso un numero qualunque a ed un numero intero positivo n, si vuole in output l'n-esima potenza di a, ossia il numero an

E' indispensabile, in questo programma, una variabile accumulatore, il cui valore FINALE sarà la potenza desiderata.

 

Esercizio 7) 

Letti in ingresso n numeri (n è fornito in input dall’utente) in parte positivi e in parte negativi, che rappresentano gli esiti (in dollari) di altrettante partite di poker,

si contano quelli negativi e se ne fa la media aritmetica;

si contano quelli positivi e se ne fa la media aritmetica.

L’output dovrà essere:

 

Hai perso … volte, perdendo in media … dollari;

e hai vinto … volte, vincendo in media … dollari.

In totale, hai (perso oppure vinto) … dollari.

 

Non è evidentemente necessario utilizzare 20 variabili diverse per ciascuno dei 20 numeri in ingresso; basterà

·         una sola variabile per la lettura;

·         una variabile accumulatore per la somma dei negativi e una variabile accumulatore per la somma dei positivi;

·         una variabile contatore per i negativi e una variabile contatore per i positivi;

·         oltre, naturalmente, alla variabile contatore della struttura FOR ... DO ...

 

Esercizio 8) 

Scrivi un programma che mandi in output tutti gli interi da 1 a 30, ciascuno colorato del colore di cui l’intero considerato rappresenta il codice (vedi capitolo 5, “Testo colorato in output”).

 

 

9) LE ALTRE STRUTTURE ITERATIVE): LA REPEAT … UNTIL … E LA WHILE … DO …

 

Una FOR ... DO ... comanda la ripetizione di un'istruzione (o di un blocco di istruzioni)

PER UN NUMERO PREFISSATO DI VOLTE.  Pertanto 

la FOR…DO… si può utilizzare solo quando è noto fin dall’inizio

quante volte l’istruzione (o il blocco) andrà ripetuto.

 

In caso contrario, si utilizza la

REPEAT … UNTIL … (RIPETI …. FINCHE’)

oppure la

WHILE … DO … (FINTANTOCHE’ … ESEGUI)

 

Esempio (struttura REPEAT … UNTIL …):

 

program somma_di_un_numero_non_prefissato_di_addendi;    uses crt;

var somma, a: integer;

begin

clrscr;

writeln ('Introduci i numeri da addizionare');

writeln ('Quando la sequenza sarà finita digita il numero 0');

somma:=0;

repeat

readln(a);

somma:=somma+a;

until a=0;

writeln ('Somma = ', somma);

readln;

end.

 

ESEGUI IL PROGRAMMA

 

 

La struttura REPEAT ... UNTIL ... ordina alla macchina di:

1.       eseguire il blocco di istruzioni  che sta fra la parola REPEAT e la parola UNTIL;

2.       controllare se è verificata oppure no la condizione che sta dopo la parola UNTIL;

se tale condizione NON E' verificata, ripetere il ciclo,

mentre se la condizione E' verificata, uscire dal ciclo.

Osserviamo che:

a)       il blocco di istruzioni viene certamente eseguito almeno una volta;

b)       il controllo se la condizione sia verificata o meno avviene  alla fine del ciclo;

c)       l' uscita dal ciclo si ha quando la condizione E’ verificata

 

Poichè con una struttura REPEAT ... UNTIL ... il ciclo viene sempre eseguito almeno una volta, tale struttura non può essere usata in quei casi in cui è necessario fare in modo che, se una data variabile assume determinati valori, il ciclo ... non venga mai eseguito!

In tali casi, si utilizza la WHILE ... DO ... (FINTANTOCHE’ … ESEGUI). Esempio:

 

Esempio (struttura WHILE … DO …):

 

program indovina;    uses crt;

var animale: string[20];

begin

clrscr;

writeln ('Caro amico che stai davanti a me, ');

writeln ('io, il computer, sto pensando ad un certo animale.');

writeln ('Prova ad indovinare di quale animale si tratta ... ');

readln (animale);

while animale <> 'orso' do

begin

writeln ('Sbagliato. Ritenta!');

readln (animale);

end;

writeln ('OK, indovinato!');

readln;

end.

 

ESEGUI IL PROGRAMMA

 

 

La struttura WHILE ... DO ... ordina alla macchina di:

·         controllare se la condizione che sta dopo la parola WHILE

è verificata oppure no;

·         se  la condizione E’ verificata, eseguire il blocco di istruzioni compreso fra le parole BEGIN e END (poi, ripetere il ciclo ricontrollando la condizione);

·         se  la condizione NON E’ verificata, uscire dal ciclo

Osserviamo che:

a)       il blocco di istruzioni può anche non essere eseguito neppure una volta;

b)       il controllo se la condizione sia verificata o meno avviene all’inizio del ciclo;

c)       l' uscita dal ciclo si ha quando la condizione NON è verificata

 

Spesso accade che una stessa iterazione possa essere realizzata,

indifferentemente, sia con una repeat ... until ... che con una while ... do ...

Esempio:

 

L'utente sceglie un numero intero n compreso fra 1 e 100.

La macchina "estrae a sorte", ripetutamente, un intero x ( 1<= x <= 100);

si contano i "tentativi" che farà la macchina prima di estrarre n.

 

program indovinatucolrepeat; uses crt;

var n, tent, x: integer;

begin

clrscr;

randomize;

write (‘n = ‘); readln (n);

tent:=0;

repeat

x:=random(100)+1;

write (x:4);

tent:=tent+1;

until x=n;

writeln;

write (tent);

readln;

end.

 

ESEGUI IL PROGRAMMA

 

program indovinatucolwhile;  uses crt;

var n, tent, x: integer;

begin

clrscr;

randomize;

write (‘n = ‘); readln (n);

x:=random(100)+1;

write (x:4);

tent:=1;

while x<>n do

begin

x:=random(100)+1;

write (x:4);

tent:=tent+1;

end;

writeln;

write (tent);

readln;

end.

 

ESEGUI IL PROGRAMMA

 

 

Ecco, ora un esempio in cui uno stesso problema di programmazione

(calcolo della somma dei quadrati dei primi n interi positivi, con n letto da tastiera)

possa essere risolto, indifferentemente, con TUTTE E TRE le strutture iterative:

 

program alfa;   uses crt;

var n, i, sommaquadrati: integer;

begin

clrscr;

write (‘n = ‘); readln(n);

sommaquadrati:=0;

for i:=1 to n do sommaquadrati:=sommaquadrati+i*i;

write (‘somma dei quadrati degli interi da 1 a ‘, n, ‘ = ‘ , sommaquadrati);

readln;

end.

 

ESEGUI IL PROGRAMMA

 

program beta;   uses crt;

var n, i, sommaquadrati: integer;

begin

clrscr;

write (‘n = ‘); readln (n);

sommaquadrati:=0;

i:=1;

repeat

sommaquadrati:=sommaquadrati+i*i;

i:=i+1;

until i>n;

write(‘somma dei quadrati degli interi da 1 a ‘, n, ‘ = ‘, sommaquadrati);

readln;

end.

 

ESEGUI IL PROGRAMMA

 

program gamma;   uses crt;

var n, i, sommaquadrati: integer;

begin

clrscr;

write (‘n = ‘); readln (n);

sommaquadrati:=0;

i:=1;

while i<=n do

begin

sommaquadrati:=sommaquadrati+i*i;

i:=i+1;

end;

write(‘somma dei quadrati degli interi da 1 a ‘, n, ‘ = ‘, sommaquadrati);

readln;

end.

 

ESEGUI IL PROGRAMMA

 

 

E per finire, un altro paio di esempi interessanti:

 

Letto in ingresso un intero positivo n, stabilire se si tratta di un numero primo.

L’algoritmo utilizzato sarà il seguente:

si va a verificare se il numero n è divisibile per 2, per 3, per 4, per 5 …

e ci si arresta non appena

·          si trova un divisore di n

·          oppure il numero che è “candidato” ad essere un divisore di n ha già superato la radice quadrata di n

(infatti si dimostra che, in tal caso, n non potrà avere alcun divisore “proprio”).

A questo punto di va a vedere se l’uscita dal ciclo è avvenuta per il fatto di aver trovato un divisore di n, oppure per l’altro motivo (ossia, per aver superato la radice quadrata di n).

In quest’ultimo caso, si conclude che n è primo, altrimenti che n è composto.

 

program vediamo_se_il_numero_dato_risulta_primo;    uses crt;

var k, n: integer;

begin

clrscr;

writeln (‘Dammi un intero e io ti dirò se è primo’);

write (‘n = ‘);  readln (n);

k:=1;

REPEAT

k:=k+1;

UNTIL (n mod k = 0) or (k>sqrt(n));

if n mod k=0 then write (n, ‘ è composto’) else write (n, ‘ é primo’);

readln;

end.

 

ESEGUI IL PROGRAMMA

 

Ora modifichiamo il programma precedente per far sì  che in output venga fornita la

sequenza di tutti i numeri primi non superiori a MAX, essendo MAX un intero letto in ingresso.

 

program sequenza_dei_numeri_primi_non_superiori_a_MAX;    uses crt;

var k, n, max: integer;

begin

clrscr;

write (‘max = ‘);  readln (max);

FOR n:=2 to max DO

BEGIN

k:=1;

REPEAT

k:=k+1;

UNTIL (n mod k = 0) or (k>sqrt(n));

if n mod k<>0 then write (n:8);

END;

readln;

end.

 

ESEGUI IL PROGRAMMA

 

 

Esercizi:

 

Esercizio 9)

Riprendi il programma

program somma_di_un_numero_non_prefissato_di_addendi;

e ribattezzalo

program prodotto_di_un_numero_non_prefissato_di_fattori;

modificandolo affinchè esegua, non più la somma, bensì il prodotto dei numeri letti da tastiera.

 

Esercizio 10)  Realizza un programma (program margherita), che faccia comparire sullo schermo il seguente OUTPUT:

1  M'AMA

2  NON M'AMA

3  M'AMA

4  NON M'AMA

……

n  ...

essendo n un numero casuale compreso fra 1 e 20.

 

INDICAZIONI

·          Puoi usare la struttura iterativa che ritieni più opportuna, ma successivamente ti chiedo di rifare il programma altre due volte, utilizzando, per utile esercizio, le due strutture iterative rimanenti.

·          Ricordiamo che il “test di parità” (vedi il paragrafo Pari? Dispari? Divisibile per … ? Divisore di …?)

si effettua mediante la funzione MOD (che dà il resto della divisione intera)

If a mod b = 0 …  significa: “se a è divisibile per b …”