Vai alla Home Page About me Courseware Federica Living Library Federica Federica Podstudio Virtual Campus 3D Le Miniguide all'orientamento Gli eBook di Federica La Corte in Rete
 
I corsi di Scienze Matematiche Fisiche e Naturali
 
Il Corso Le lezioni del Corso La Cattedra
 
Materiali di approfondimento Risorse Web Il Podcast di questa lezione

Silvia Rossi » 6.Le strutture di controllo - parte seconda


Le istruzioni cicliche o iterative: for e while

Ciclo o iterazione: un gruppo di istruzioni che può essere ripetuto più volte.

Supponiamo di avere a disposizione 10 raggi e di voler calcolare 10 circonferenze. L’algoritmo sarà allora:

ripeti 10 volte:
leggi(raggio)
circonferenza ←2* 3.1415*raggio
stampa(circonferenza)

In via del tutto generale l’utente dice al programma quante circonferenze deve calcolare come segue:

leggi(n)
ripeti n volte:
leggi(raggio)
circonferenza←2* 3.1415*raggio
stampa(circonferenza)

C++ istruzioni iterative

Istruzione ciclica for:
for (inizializza; condizione; modifica) { istruzione; … }
dove:

  • inizializza é un’espressione eseguita la prima volta, (serve per inizializzare le variabili di ciclo);
  • condizione é un’espressione logica;
  • modifica é un’espressione eseguita alla fine di ogni iterazione (serve per aggiornare le variabili di ciclo);
  • il programma esegue ripetutamente il blocco di istruzioni finché la condizione é true e passa all’istruzione successiva appena la condizione diventa false.

C++ istruzioni iterative (segue)

Implementiamo in C++ l’algoritmo per calcolare n volte la circonferenza di un cerchio.
Si veda l’esercizio 6.1.


Esempio

Assegnato un numero n compreso tra 1 e 10, stampare la tabellina relativa a un numero preassegnato. Per es. se n=4 deve stampare
4×1=4 4×2=8 4×3=12 ……………………………..4×10=40
L’algoritmo relativo diventa:

leggi(numero)
for (i_1;i<=10;++i)
stampa(numero*i)

Il corrispondente codice C++ è dato da:

cin>>numero
for (int i=1;i<=10;i++)
cout<<numero<<"x"<<i<<" ="<<numero*i;

Si noti che la variabile i viene dichiarata all’interno dello stesso for.
Può essere usata solo all’interno del for stesso (visibilità/scope).
La visibità di una variabile definisce in quali parti del programma può essere utilizzata.

Il ciclo for può essere utilizzato solo se si conosce a priori quante volte il corpo del ciclo deve essere ripetuto.

Si veda l’esercizio 6.2

Si veda l’esercizio 6.3

Esercizio

Sommare gli interi pari compresi tra 2 e 20…

Si veda l’ esercizio 6.4

C++ istruzioni iterative

Tornando al problema del calcolo della circonferenza si vuole consentire all’utente di calcolare un numero imprecisato circonferenze fino a quando non si dà un raggio uguale a zero.
Un possibile algoritmo è il seguente:

leggi (raggio)
finchè raggio!=0 ripeti:
circonferenza ←2* 3.14*raggio
stampa(circonferenza)
leggi(raggio)

Qui sappiamo che il corpo del ciclo deve essere eseguito ogni volta che il numero letto è diverso da zero.
In questi casi possiamo ricorrere al ciclo while.

C++ istruzioni iterative (segue)

Istruzione ciclica while:

while (condizione) { istruzione; ... }

dove:

  • condizione é un’espressione logica che viene verificata all’inizio di ogni iterazione del ciclo:
    • se la condizione é già inizialmente false, il ciclo non viene eseguito mai;
  • il programma esegue ripetutamente il blocco di istruzioni finché la condizione é true e passa all’istruzione successiva appena la condizione diventa false;
  • affinché il loop (ciclo) non si ripeta all’infinito, il blocco di istruzioni deve modificare qualche parametro della condizione.

C++ istruzioni iterative (segue)

Si veda l’ esercizio 6.5


C++ istruzioni iterative (segue)

Il corpo del loop può essere un’istruzione semplice o composta.
Supponiamo di dover ripetere un gruppo di istruzioni soltanto nel caso che a sia minore di b, con a e b numeri interi.

Scriveremo qualcosa del tipo:

while (a < b
{
(gruppo di istruzioni da ripetere)
}

Il gruppo di istruzioni all’interno del ciclo è il corpo del ciclo, l’espressione booleana (a<b) viene chiamata condizione di ingresso; la sua negata rappresenta la condizione di uscita dal ciclo.

Una singola esecuzione della sequenza di istruzioni che formano il corpo del ciclo è detta passo del ciclo.

C++ istruzioni iterative (segue)

Siano a e b due numeri interi i cui valori iniziali sono: a=5; b=10; (rappresentano le inizializzazioni delle variabili del ciclo necessarie per poter valutare l’espressione booleana; se fosse b=10 e a=12 il ciclo non verrebbe proprio eseguito). Si veda l’esercizio 6.6
Quale sarà il valore di a che verrà stampato alla fine del ciclo? Dopo l’inizializzazione con a=5 e b=10 entriamo nel ciclo while (la condizione (a<b) è vera)

  • otteniamo a=6 e b=9

Si ritorna alla condizione di controllo del ciclo, (a<b), e poichè 6<9, si esegue un altro ciclo

  • a=7 e b=8

Si ritorna ancora al controllo (a<b), si verifica che 7<8

  • a=8 e b=7

la condizione (a<b) è falsa per cui si salta il ciclo e si esegue l’istruzione. Subito dopo il computer scriverà sul video a=8.



C++ istruzioni iterative (segue)

Problema: somma di n numeri

  • Dato un numero intero positivo n supponiamo di voler calcolare la somma dei primi n numeri interi positivi: Somma = 1 + 2 + … + n
  • Algoritmo 1:
    • Definiamo una variabile contatore che assuma come valore, di volta in volta, i numeri interi da 1 a n
    • Definiamo una variabile somma che conterrà le somme parziali:
      • contatore = 1, somma = (0) + 1 = 1
      • contatore = 2, somma = (0+1) + 2 = 3
      • contatore = 3, somma = (0+1+2) + 3 = 6

La condizione di iterazione è contatore ≤ n

I valori che abbiamo posto tra parentesi rappresentano la somma ottenuta al passo precedente;
somma=somma+contatore;
somma+=contatore;


Esempi

Algoritmo 1  – Somma dei primi n interi

inizializza contatore a 1 e somma a 0
while contatore <= N ripeti:

incrementa il valore della variabile somma con il contenuto di contatore
incrementa il contatore di 1
Altra possibilità è di inzializzare sia contatore che somma a zero; in tal caso l’algoritmo si modifica come segue:

Algoritmo 2

inizializza contatore e somma a 0
while contatore < N ripeti

incrementa il contatore di 1
incrementa il valore della variabile somma con il contenuto di contatore

Off by one

Algoritmo 3

inizializza contatore e somma a 0
finché contatore <= N esegui le due istruzioni

incrementa il contatore di 1
incrementa il valore della variabile somma con il contenuto di contatore

Algoritmo 4

inizializza contatore ad 1 e somma a 0
finché contatore < N ripeti

incrementa il valore della variabile somma con il contenuto di contatore
incrementa il contatore di 1

C++ istruzioni iterative

Si veda l’ esercizio 6.7


C++ istruzioni iterative (segue)


Ciclo Infinito

Se la condizione all’interno del while non è tale da rendere ad un certo punto la condizione falsa, si ha un ciclo infinito perché il programma non ha mai modo di terminare.

Questo può far sembrare il programma bloccato.

C++ istruzioni iterative (segue)

Esempio: calcolo del MCD di due numeri naturali a e b
Algoritmo di Euclide ( ∼ 300 A.C.):

  1. Dividere a per b
  2. Se il resto r è nullo MCD è b
  3. Altrimenti assegna a_b e b_r e torna la passo 1.

C++ istruzioni iterative (segue)

Input a,b
Finché il resto della divisione tra a e b è diverso da zero esegui le istruzioni:

Calcola il resto dei due numeri interi a e b
Poni b in a (poni il divisore nel dividendo)
Poni il resto della divisione in b
Quando il resto è zero allora il MCD è il numero intero contenuto in b
Scrivi il MCD b

Notiamo che, poiché il ciclo termina quando il resto della divisione è zero, non è perfettamente determinato il numero di  passi da eseguire: in tal caso non è possibile utilizzare il ciclo for ma è necessario servirsi del while.

C++ istruzioni iterative (segue)

Si veda l’ esercizio 6.8


C++ uso del debug – Debug del programma per il calcolo MCD con DevCpp

  • Impostiamo la compilazione in modo da generare informazioni di debug
    • Strumenti → Opzioni di compilazione → Generazione di codice/Ottimizzazione → Linker → Genera informazioni di debug (Yes)
  • Ricompiliamo il codice
  • Inserimento del breakpoint
    • cliccare con il mouse alla sinistra della istruzione di beakpoint
    • il breakpoint è un punto di arresto dell’esecuzione del programma, che consente di proseguire passo passo nell’esecuzione
  • Eseguiamo il programma fino al breakpoint
    • Clicchiamo il tasto di Debug nella finestra di debug (l’esecuzione si arresta al breakpoint)
  • Specifichiamo le variabili di osservazione:
    • Nella finestra “Debug” clicchiare su Nuova Osservazione e immettere il nome della variabile da osservare
    • Le variabili con i valori sono visualizzate nella parte sinistra dell’intefaccia
  • Per eseguire istruzione dopo istruzione
    • Cliccare su Step succ.
  • Per eseguire fino alla fine o al prossimo breakpoint
    • Cliccare su Step esterno
  • Per interrompere l’esecuzione
    • Cliccare su Fema l’esecuzione

C++ uso del debug (segue)


Esercizi

1- Tenendo presente il programma che calcola la somma dei primi N numeri interi scrivere un programma che determini:

  • la somma di tutti i numeri pari e la somma di tutti i numeri dispari inclusi tra 1 ed N;
  • la differenza tra i due valori ottenuti;
  • la somma di tutti gli inversi tra 1 ed N, cioè: 1 + 1/2+1/3 +…+1/n.

2- Dato il programma che calcola il Massimo Comun Divisore:
verificare cosa accade se i valori immessi sono entrambi negativi, uno negativo e l’altro positivo, uno positivo ed uno nullo. Apportare al programma le modifiche necessarie affinché dia sempre risposte coerenti.

Esercizi (segue)

Calcolare il prodotto dei primi N interi.
Viene spontaneo sostituire il simbolo del prodotto al posto di quello della somma. Se provate a farlo otterrete uno strano risultato: utilizzate il debug (o, ancora meglio, ragionateci sopra).

Quali modifiche devono essere apportate nel programma per eseguire la somma di tutti gli interi inclusi tra due numeri N1 ed N2 prefissati (con N1< N2) ?

Calcolo della Conversione da decimale a Binario.

Progetto "Campus Virtuale" dell'Università degli Studi di Napoli Federico II, realizzato con il cofinanziamento dell'Unione europea. Asse V - Società dell'informazione - Obiettivo Operativo 5.1 e-Government ed e-Inclusion