Rappresentazione delle informazioni numerilaurap/didattica/... · Rappresentazione delle...

Post on 20-Jun-2020

2 views 0 download

Transcript of Rappresentazione delle informazioni numerilaurap/didattica/... · Rappresentazione delle...

1

Rappresentazione delle informazioni

Rappresentazione delle informazioni

• L’informatica si occupa di rappresentare ed elaborare

informazioni:

• numeri

• caratteri

• audio

• immagini

• video

Rappresentazione dei caratteri

I caratteri

• I caratteri appartenenti ad un alfabeto vengono codificati (cioè “rappresentati”) mediante sequenze di bit: una diversa sequenza per ciascun diverso carattere.

• Uno dei codici più noti e usati è il codice ASCII (American Standard Code forInformation Interchange):• usa una sequenza di 7 bit per ciascun carattere: ci

sono 128 (=27) sequenze diverse, utilizzate anche per lettere, segni di punteggiatura, cifre decimali, ecc.

(par. 6.9)

2

I caratteri

• Dato che l’unità elementare di informazione nei calcolatori è il byte (= 8 bit), si è passati ad usare, quasi sempre, il codice ASCII esteso,che usa una sequenza di 8 bit per ciascun carattere degli alfabeti occidentali:

• ci sono 256 (=28) sequenze diverse, utilizzate anche per vocali accentate e altre lettere speciali (es. ß tedesca, ç francese)

• le sequenze con la prima cifra uguale a zero coincidono con il codice ASCII

I caratteri

• I primi 32 caratteri del codice ASCII (con codice da 0 a 31) sono caratteri di controllo: • 9 tabulatore ’\t’

• 10 nuova riga ’\n’

• 13 invio ’\r’

• I caratteri da 32 a 127 sono caratteri stampabili:• 32 spazio ’ ’

• da 48 a 57 caratteri numerici, le cifre decimali ’0’, ’1’…

• da 65 a 90, da 97 a 122 caratteri alfabetici (maiuscoli e minuscoli)

• da 33 a 47, da 58 a 64, da 91 a 96, da 123 a 127 caratteri di interpunzione.

I caratteri (codice Unicode)

• Per rappresentare i segni grafici utilizzati da tutti gli alfabeti del mondo servono molti piùsimboli diversi.

• Codifica Unicode

http://www.unicode.org• usa una sequenza di 16 bit per ciascun

segno grafico:• ci sono 65536 (= 216) sequenze diverse

• le sequenze con le prime otto cifre uguali a zero coincidono con il codice ASCII esteso.

I caratteri (codice Unicode)

3

Variabili e Tipi base

Variabili e Tipi base

• Nei corsi di matematica quando scriviamo

x ∈∈∈∈ ����

e diciamo “ x è una variabile reale” intendiamo dire che x è un nome che indica un elementogenerico dell’insieme ���� dei numeri reali.

• Nei corsi di informatica con “x è una variabile reale” intendiamo dire che x è un nome che indica una posizione di memoria che conterràun elemento generico di R (con R ⊂⊂⊂⊂ ����).

Variabili e Tipi base

• ���� insieme dei numeri reali (infinito e

continuo).

• R insieme dei numeri reali rappresentabili nel calcolatore (finito e discreto).

• La posizione di memoria è caratterizzata dal tipo, che è l’insieme da cui la variabile può estrarre i suoi valori

3 reale è diverso da 3 intero

Variabili e Tipi base

• Ogni variabile possiede:

• un nome: è una stringa di caratteri che è bene ricordi il significato della variabile,

• un tipo: è l’insieme da cui la variabile può estrarre i valori,

• regole d’uso: rappresentano l’insieme delle operazioni che si possono fare sulla variabile,

• struttura: alla variabile può essere associato un solo valore oppure gruppi di valori dello stesso tipo o di tipo diverso,

• ambito d’uso: è l’ambito di visibilità, indica in quale punto del programma è nota e quindi usabile.

4

Variabili e Tipi base

• Tipi base o primitivi o standard nel C++• numeri interi short, int, long

• numeri reali float, double

• caratteri char

Non fanno parte dello standard ma sono implementati

• logici bool

• Definizione di una variabile

• Sintassi

nometipo nomevariabile;

Variabili e Tipi base

• Esempi.

int n, numeroanni;

short dimensione;

double area, saldo;

bool errore;

char lettera;

• Non si possono ridefinire le variabili.

Variabili e Tipi base

• Le operazioni che possiamo fare su unavariabile sono:

• accesso : individuare la posizione di memoria ed estrarre il valore (lettura)

• assegnamento : individuare la posizione di memoria e introdurre il valore (scrittura)

Variabili e Tipi base

• Nelle istruzioni di un programma, abbiamo:

• accesso: quando la variabile compare in una istruzione e se ne utilizza il valore

• assegnamento: quando il valore le viene attribuito:

• dall’esterno: lettura del valore in una acquisizionedi dati

• in una istruzione di assegnazione

5

Assegnazione

Assegnazione

• Sintassi:

nomevariabile = espressione;

• Esempi.

n = 3+5;

area = 25.67;

saldo = 20000;

lettera = 'x';

lettera = x ; //Errore

Assegnazione

• Quando una variabile viene definita le viene associata un’area di memoria del tipo attribuito con la definizione:

int a;

double b;

a b

• Interi e reali vengono rappresentati in binario in modo diverso.

Assegnazione

• Quando si esegue l’assegnazione, il valore viene inserito nell’area corrispondente

a=3;

b=3;

a b

• Le due aree di memoria sono di tipo diverso e la sequenza di bit (per il numero 3) contenuta èdiversa, anche con uguale numero di bit (long e float).

3 3

6

Assegnazione

• Il simbolo per l’istruzione di assegnazione è

= (C++, Java, Fortran)

• NON lo si deve confondere con un simbolo di uguaglianza o di confronto.

• Il suo significato è:

• il valore dell’espressione a destra del simbolo =viene inserito nella locazione corrispondente alla variabile che sta a sinistra.

• Nel Pascal, il simbolo è := proprio per distinguerlo dal simbolo di uguaglianza

Assegnazione

• Si può eseguire una assegnazione anche in fase di definizione:

int k = 25;

• Osserviamo queste assegnazioni e vediamo un diverso significato per a:

a = 5; //assegnamento su a

//a è a sinistra

k = a; //accesso per a

//a è a destra

Assegnazione

• Osserviamo queste assegnazioni:a = 5; //assegnamento

a = a + 1; /*sia accesso che assegnamento*/

• Quanto vale a?

a = a + 1;

• In alcuni linguaggi di pseudocodifica, il simbolo per l’assegnazione è ←←←←

5 6

Assegnazione

• Nei primi linguaggi le variabili avevano per il tipo una definizione di default. In C++ una variabile può essere usata solo se è stata precedentemente definita, ossia se è stata dichiarata con il suo tipo.

• Esempio.

int c = 7;

c1 = c; //Errore: c1 non è definita

Il compilatore segnala:

error : C1 undeclared

7

Assegnazione

• Nell’assegnazione si deve rispettare il tipo di dato.

• Esempio.char m;double y = 23.75;

m = y; //NO: m è un carattere

Il compilatore segnala:warning: converting to char from

double

• Il compilatore C++ non è molto preciso. L’errore si verifica in esecuzione.

Leggere dati in ingresso

Leggere dati in ingresso

• Per dare un valore iniziale ai dati possiamo utilizzare l’istruzione di assegnazione: in tale modo, però, avremo sempre la stessa elaborazione ad ogni esecuzione.

• Se vogliamo eseguire il programma su altri dati, è necessario modificare il codice sorgente e quindi le inizializzazioni delle variabili e compilarlo di nuovo, prima di eseguirlo.

Leggere dati in ingresso

• Per poter scrivere programmi generali, l’utente deve poter inserire dei propri dati: i programmi devono perciò ricevere dati in ingresso, acquisire valori dall’esterno.

• Lo scambio di informazioni tra l’utente e il programma e viceversa è rappresentato da un flusso di dati.

• Quando l’ingresso è rappresentato dalla tastiera si dice che il programma viene eseguito in maniera interattiva: durante l’esecuzione il programma si ferma in “attesa” di ricevere i dati (input).

8

Leggere dati in ingresso

• Il flusso di dati standard per l’uscita è un file di nome cout; il flusso di dati standard per l’ingresso è un file di nome cin.

• Ciò che viene inserito da tastiera viene codificato in binario e successivamente ricostruito prima come gruppo di caratteri (stringa) e poi interpretato come valore di una variabile di un certo tipo.

Leggere dati in ingresso

• Esempio.

3 3 intero7.5 7.5 realeciao 0100110…01 ciao stringa

true true booleano

Leggere dati in ingresso

• Esempio.int a; double b;

cin>>a>>b;

• Per acquisire il valore per due variabili si può concatenare l’operatore d’ingresso >> oppure si possono eseguire due istruzioni di lettura:

cin>>a;

cin>>b;

• In entrambi i casi i dati devono essere immessi rispettando l’ordine (un numero intero e un numero reale) ma possono essere scritti sulla stessa riga, separati da spazio oppure su righe diverse.

Progettare Algoritmi

9

Progettare Algoritmi

• La progettazione di un algoritmo è una fase che richiede intelligenza e fantasia: l’informatica è un’arte.

• Per imparare a progettare un algoritmo ci può aiutare la scomposizione del problema in problemi più semplici e la scrittura dell’algoritmo in un linguaggio intermedio(pseudocodifica) nel quale evidenziare i costrutti importanti senza vincoli di sintassi.

Progettare Algoritmi

• Scomporre un problema P in sottoproblemi significa individuare problemi più semplici P1, P2, P3 che risolti nell’ordine costituiscono la soluzione.

• Ciascuno dei sottoproblemi può a sua volta essere scomposto nuovamente.

P1 P2 P3

P

Progettare Algoritmi

• Fino a quando si prosegue con queste successive scomposizioni?

• Si prosegue fino al livello di operazioni elementari (operazioni aritmetiche, confronti, ecc.) o fino ad incontrare problemi già risoltiin precedenza da noi (es. algoritmi di somma, ricerca, ordinamenti,…) o da altri (funzioni matematiche sin(x), gestione di array,…).

Progettare Algoritmi

• Nel linguaggi ad alto livello (Pascal, C, Java,..) ci sono degli enunciati che organizzano le istruzioni con precisi significati: strutture dicontrollo.

• Sono essenzialmente tre: sequenza, scelta (decisioni), ciclo (iterazioni).

• Teorema di Bohm-Jacopini 1966: ogni algoritmo può essere scritto utilizzando unicamente queste tre strutture.

10

Strutture di controllo

Strutture di controllo

• Una struttura di controllo è un blocco di istruzioni caratterizzato da un unico punto di ingresso e un unico punto di uscita e che si può schematizzare nel modo seguente:

(par. 1.5.2)

SS

Strutture di controllo

• In tale modo l’algoritmo si può schematizzare:

prima 2)

successiva 3)

ultima 4)

S1

Si

Si+1

Sn

Sequenza

• Si chiama sequenza una funzione che ha per dominio un sottoinsieme finito dei � e il cui codominio acquisisce l’ordine posizionale degli elementi di � .

• Indichiamo con Nk = {1, 2, 3, .., k}

s : Nk → A

• Il codominio di s = {s(1), s(2), … s(k)}, ma solitamente si scrive:

s1, s2, s3, …. sk

• si+1 è il successivo di si, come posizione e non come valore.

11

Sequenza

• La struttura di controllo sequenza rappresenta un gruppo di istruzioni eseguite secondol’ordine posizionale (che nei linguaggi èl’ordine di scrittura delle istruzioni):

<istruzione 1>

<istruzione 2>

.……………

<istruzione k>

• Cosa può essere <istruzione i> ?

Sequenza

• La generica istruzione può essere:

• assegnazione

• struttura di controllo

• operazione lettura/scrittura

• invocazione di una funzione (sottoprogramma)

Esercizio

• Problema: Si consideri un trapezio T i cui angoli alla base maggiore sono rispettivamente 30° e 45°. Sono

note le misure dei lati AB = 60 cm.(base maggiore) e AD = 20 cm. (il lato obliquo che forma 30° con la

base). Calcolare il perimetro e l’area del trapezio.

D C

A K H B

Esercizio

• Analisi del problema.

• Vediamo di generalizzare alcuni dati: possiamo voler risolvere il problema per dei valori generici di AB e AD (purché AB >AD).

• Non possiamo invece considerare un valore qualunque per gli angoli alla base, perchéforniscono importanti relazioni per individuare le misure degli altri lati.

12

Esercizio

• Il problema propone già una scomposizione:

• I scomposizione:

• P si suddivide in

• P1 : calcolare il perimetro

p = AB+AD+DC+CB

• P2: calcolare l’area

area = (AB+DC)*CH /2

Basi di conoscenza: sappiamo le formule

Esercizio

• Il problema P1 non è subito risolubile, ma necessita di una ulteriore scomposizione:

• II scomposizione per P1:

• Ci mancano le misure dei lati DC e CB, quindi la scomposizione sarà

• P1.1 calcolare DC

• P1.2 calcolare CB

• P1.3 calcolare il perimetro p = AB+AD+DC+CB

Esercizio

• Come facciamo a calcolare DC?

• Il problema P1.1 deve essere ulteriormente scomposto:

DC = AB – AK –HB ed è noto solo AB

• P1.1.1 AK = AD * √ 3 /2

• P1.1.2 HB = CH = DK = AD/2

• P1.1.3 DC = AB-AK-HB

Esercizio

• P1.2 calcolare CB:

CB = HB * √2 (HB calcolato)

• P1.3 calcolare il perimetro.

• Sequenza dei sottoproblemi che risolve P1:

(P1.1.1 P1.1.2 P1.1.3) P1.2 P1.3

13

Esercizio

• Vediamo ora la seconda scomposizione per P2:

• Poiché P2 è il secondo sottoproblema:

• DC è noto

• CH = HB è noto

(noti perché calcolati nella soluzione per P1)

• Area = (AB+DC)*HB/2

Esercizio

• La scomposizione finale è una sequenza:

P1.1.1 AK

P1.1.2 HB = CH

P1.1.3 DC

P1.2 CB

P1.3 perimetro

P2 area

Esercizio per casa

• Esercizio: scrivere in C++ le istruzioni di questo algoritmo (sono tutte assegnazioni, ma bisogna rispettare l’ordine).• Il valore degli angoli è servito per costruire le

relazioni e non è un dato da inserire; calcolare a parte la radice di 2 e di 3.

• Esercizio. Calcolare la misura della diagonale del rombo equivalente agli 8/5 del trapezio essendo note le misure dell’altra diagonale.

Predicati

14

Predicati

• Un predicato è una funzione a valori nell’insieme B B B B

P: A → B B B B

x ∈ A P(x) può essere vero o falso

• x deve avere un valore, altrimenti il predicato non èvalido.

Esempio. A = ���� P(x) : x > 5

P(7) è vero P(3) è falso

Struttura condizionale

Struttura condizionale

• Struttura condizionale o decisione o scelta.

• Sia P un predicato (condizione); P viene valutato e sarà o vero o falso. Si vuole eseguire <istruzione1> nel caso in cui P sia vero e <istruzione2> nel caso in cui P sia falso.

• Come possiamo esprimere in un costrutto questa scelta?

se P

allora istruzione1 //P vero

altrimenti istruzione2 //P falso

//fine scelta

Struttura condizionale

• Può anche accadere che non dobbiamo fare nulla nel caso in cui P sia falso; allora possiamo schematizzare questa scelta in modo seguente:

se P

allora istruzione

//fine scelta

• L’ingresso alla struttura è la valutazione del predicato P, l’uscita è la fine della scelta (istruzione successiva o fine algoritmo).

15

Struttura condizionale

• Esempio.

• Dati due numeri reali a e b, determinare il piùgrande dei due.

• Analisi.

• Tra le operazioni elementari sui numeri non c’è il calcolo del massimo, quindi dobbiamo utilizzare una struttura condizionale: il predicato sarà rappresentato dal confronto tra i due numeri; il confronto è una operazione elementare.

Struttura condizionale

• Progetto.Algoritmo massimotradue

variabili a, b, max di tipo reale

acquisire i dati per a e b e stamparli

se a>b

allora max ←←←← a

altrimenti max ←←←← b

//fine scelta

stampare il valore di max

//fine algoritmo

Struttura condizionale

• La struttura if. Sia P un predicato o una espressione; il vero del predicato corrisponde a “diverso da zero”, il falso del predicato corrisponde a “0” (par.13.7.1).

• La sintassi è:

if(P)istruzione;

if(P){//blocco di istruzioni

………istruzione;………

}

se P

allora istruzione

//fine scelta

Struttura condizionale

• L’unica istruzione, o il blocco di istruzioniindividuato dalla coppia di parentesi graffe, viene eseguita solo nel caso in cui il predicato P risulti vero.

• Esempio.int a, b;

//assegnare valori ad a e b

if(a>b)

cout<<""""a maggiore di b"""" <<endl;

16

Struttura condizionale

• Sintassi con le due alternative; sia P la condizione:if (P)

istruzione;

else

istruzione;

if(p){//blocco

istruzione;

}

else{//blocco

istruzione;

}

se P

allora istruzione

altrimenti istruzione

//fine scelta

Struttura condizionale

• Attenzione al ;

• Dopo la parentesi graffa (prima di else) non ci deve essere il simbolo ;

• Se si mette il ; l’istruzione if termina e il compilatore segnala che c’è una else senza if

if(x>0){

cout<< """" x = """" << x <<endl;

cout<<"""" x positivo \n"""";

};

else ...

il compilatore segnala:

error: parse error before else

Struttura condizionale• Traduciamo l’algoritmo massimotradue

int main () {

double a,b, max;

cin>>a>>b; //acquisire e stampare a e b

cout<<"a = "<<a<<" b = "<<b<<endl;

if (a>b)

max = a; //P vero

else

max = b; // P falso

cout<< """" il massimo vale: max = """" <<

max<<endl;

return 0;

}//fine main

Struttura condizionale

• Possiamo voler eseguire due istruzioni, quindi usare un blocco:

if (a>b) {

max = a; //P vero

cout<<""""a > b"""" <<endl;

}

else {// P falso

max = b;

cout<<""""a <= b"""" <<endl;

}//fine if

cout<<" " " " max = """" << max<<endl;

17

Struttura condizionale

• L’istruzione

cout<<" " " " max = """" << max<<endl;

• viene eseguita con qualunque valore di P (vero, falso) e rappresenta il punto di prosecuzione dell’esecuzione dell’algoritmo.

• Ma se abbiamo più scelte come possiamo scriverle? In sequenza o annidate?

Struttura condizionale

• Scelte multiple. Siano P e Q due predicati:

if (P)

istruzione; //if in sequenza

if(Q)

istruzione;

. . . . . . . . . . . . . . . . .

if(P) //if annidate

istruzione;

else if(Q) // if(Q) si valuta

istruzione; //quando P è falso

Struttura condizionale

• Nella sequenza il predicato Q viene valutato in ogni caso: P vero e P falso; nel caso di ifannidate, il predicato Q viene valutato solo se P è falso.

• Quale delle due strutture scegliere dipende da ciò che si vuole realizzare nell’algoritmo. L’ordine con cui si effettuano le scelte può essere fondamentale per l’algoritmo: un ordine diverso può dare un algoritmo errato.

Struttura condizionale

• Esempio. Supponiamo di voler stampare una stringa che esprima la ricchezza o meno di una persona in base al suo saldo bancario.

povero medio ricco straricco

0 1000 50000 200000

• Dopo aver acquisito il valore del saldo (double) eseguiremo i vari confronti con i valori che individuano gli intervalli di minore o maggiore ricchezza stabilendo un valore da stampare (un carattere che esprime la ricchezza: p, m, r, s).

18

Struttura condizionale

char s; double saldo;

if(saldo >= 200000)

s='s';

else if(saldo >= 50000)

s='r';

else if(saldo >= 1000)

s='m';

else if(saldo >=0)

s='p';

else s='N'; //valore non valido

cout<<"s = "<<s<<endl;

Struttura condizionale

• Casi di prova.

• Per essere sicuri che la struttura funzioni bene dobbiamo provare tutte le alternative, provando diversi valori per saldo:

-2 900 1000 1200 51000 200000 250000

• In corrispondenza a questi valori ci aspettiamo un valore per s: non valido, povero, medio, medio, ricco, straricco, straricco.• Se nel predicato si mette > invece di >=il secondo e il quarto valore di s cambiano.

Struttura condizionale

• Proviamo ad invertire l’ordine delle scelte:if(saldo >= 1000)

s='m';

else if(saldo >= 0)

s='p';

else if(saldo >= 50000)

s='r';

else if(saldo >= 200000)

s='s';

else s='N';

• Per saldo = 1200 si ha s= “m” e le altre scelte nonvengono eseguite; ma cosa accade per saldo = 51000?

Struttura condizionale

• Se mettiamo le if in sequenza otteniamo:if(saldo >= 200000)

s='s';

if(saldo >= 50000)

s='r';

if(saldo >= 1000)

s='m';

if(saldo >=0)

s='p';

//else s='N';

cout<<"s = "<<s<<endl;

• Viene, però, sempre stampato l’ultimo valore perché le assegnazioni sono in sequenza .

19

Struttura condizionale

• Esercizio. Scriviamo delle istruzioni che autorizzano il prelievo da un conto corrente solo se l’ammontare del prelievo è inferiore al saldo:

double saldo = 10000; //saldo iniziale

double prelievo = 200;

if (prelievo <= saldo )

saldo = saldo - prelievo;

cout<<""""restano """" << saldo << """" euro \n"""";

Struttura condizionale

• E se il prelievo è superiore? Il programma deve dare una risposta anche nel caso in cui il prelievo sia superiore al saldo e …. impedirlo: il saldo non può essere negativo.if (prelievo <= saldo )

saldo = saldo - prelievo;

if (prelievo > saldo)

cout<<"impossibile: conto scoperto\n";

• In questo algoritmo c’è un errore logico.

Struttura condizionale

• Se il prelievo viene eseguito ma supera la metà del saldo la seconda if viene eseguita e stamperà“impossibile”, perché il saldo è stato modificato. Pertanto eseguiamo le istruzioni in alternativa:

if (prelievo <= saldo )

saldo = saldo - prelievo;

else

cout<<"impossibile: conto scoperto\n";

Struttura condizionale

• If annidate e il problema dell’else sospeso .

• Siano P e Q due predicati; non essendoci un costrutto “endif” si pone il seguente problema:

if(P)

if(Q)

istruzione1;

else istruzione2;

• La else a quale delle due if si riferisce?

20

Struttura condizionale

• Esempio.int a,b,c;

a=9; b=7; c=4;

if (a>b) //vero

if(b<c) //falso

b=b+1;

else b=b-1;

cout<<"""" b = """" << b<<endl;

• Quale valore viene stampato per b? 6 o 7?

• La else si riferisce alla prima if o alla seconda?

Struttura condizionale

• La regola del linguaggio è la seguente:

• La else si riferisce alla if più vicina (interna) quindi b=6.

• Si può alterare la regola inserendo della parentesi graffe:

int a,b,c; a=9; b=7; c=4;

if (a>b){ //vero

if(b<c) //falso

b=b+1;}

else b=b-1; //si riferisce alla prima

cout<<"""" b = """" << b<<endl; //b=7

Un po’ di stile

• Quando scriviamo una struttura è bene utilizzare una modalità di scrittura che faciliti la lettura dell’algoritmo, rientrando di alcuni spazi a sinistra le istruzioni che si riferiscono al vero e al falso, ed incolonnando le else sotto la parola if.

• Però questo stile non risolve l’attribuzione della else in caso di più strutture condizionali, che si ottiene con l’inserimento (o meno) della coppia di parentesi graffe.

Struttura iterativa

21

Struttura iterativa

• Consideriamo un predicato P e valutiamo se èvero: nel caso vero vogliamo eseguire ripetutamente un gruppo di istruzioni; questo gruppo di istruzioni, però, non dovrà più essere eseguito nel caso in cui P sia falso. Possiamo rappresentare questo ciclo scrivendo che:

fintantoché P eseguire

<istruzioni> //P vero

//fine ciclo

// ora P è falso

Struttura iterativa

• Individuiamo così una struttura con un unico punto di ingresso (la valutazione di P) ed un unico punto di uscita (ciò che segue dopo la fine della struttura).

• Esempio.

• Stampare i primi cinque numeri naturali in ordine decrescente.

• Analisi. Dobbiamo:

1. individuare il predicato P

2. individuare le istruzioni da ripetere.

Struttura iterativa

• Quali sono i numeri da stampare?

• 1, 2, 3, 4, 5 ma nell’ordine inverso:

5, 4, 3, 2, 1

• Possiamo pensare di partire dal più grande (5) e ad ogni iterazione calare di una unità, quindi l’iterazione sarà:

stampa numero

esegui numero-1

• Quando ci fermiamo? Lo 0 non è compreso, quindi fintantoché numero è maggiore di zero, ripetiamo le istruzioni.

Struttura iterativa

• Progetto.

algoritmo stamparovescia

variabili a intero

a ←←←← 5

finché a > 0 eseguire

stampa a

a ←←←← a-1

//fine struttura

• Questa struttura termina?

22

Struttura iterativa

• Scriviamo i valori che la variabile a assume durante il funzionamento dell’algoritmo:

valore predicato stampa

a > 0

a = 5 V 5

a = 4 V 4

a = 3 V 3

a = 2 V 2

a = 1 V 1

a = 0 F il ciclo termina

Struttura iterativa

• Osserviamo che il ciclo è stato eseguito 5 volte e che il predicato è stato valutato 6 volte:

5 vero + 1 falso

• Qual è il comportamento di un ciclo?

• Un ciclo:

• può non essere mai eseguito

• può essere eseguito una o più volte

• deve terminare.

Struttura iterativa

• Cosa cambia se iniziamo con a = -5 ?• Il predicato a > 0 è falso e quindi il ciclo non viene

mai eseguito. Se quello che volevamo era la stampa dei numeri, questo è un errore logico: il compilatore non segnalerà errore ma il programma non eseguiràle operazioni richieste.

• Cosa cambia se scriviamo a ← a+1?

• I valori da a saranno: 5, 6, 7, … il predicato saràsempre vero e il ciclo non termina. Questo è un errore logico grave.

• Nell’iterazione ci deve sempre essere una istruzione che modifica il predicato e che può renderlo falso.

Struttura iterativa

• Il ciclo while (par. 13.7.3).• Sia P un predicato (espressione), la sintassi è:

while (P)

istruzione;

while (P){//blocco

. . . . .

istruzione;

. . . .

}//fine while

finché P eseguire

iterazione

//fine ciclo

23

Struttura iterativa

• Esempio. Scrivere un algoritmo per stampare i numeri dispari compresi tra 1 e 10.

//inizio algoritmo

int i = 1;

while(i <= 10) {

cout<<i<<endl;

i = i+2;

}

Verifica: i assume i valori 1, 3, 5, 7, 9, con predicato

vero; quando i = 11 il predicato è falso e il ciclo termina.

Struttura iterativa

• Il ciclo precedente è del tipo:

indice = inizio;

while(indice <= fine){

//iterazione;

indice = indice + passo;

}

• Questo ciclo è governato da un’unica variabile (indice) che descrive un intervallo di valori e che èincrementata di una quantità fissa (passo).

Struttura iterativa

• Il ciclo for (par. 13.7.4) .

• La sintassi è:

for (inizializzazione; controllo; modifica)

iterazione;

• Oppure:

for (inizializzazione; controllo; modifica){

//blocco di istruzioni

}

Struttura iterativa

• Nel caso precedente il ciclo while si trasforma

in:

for (indice = inizio; indice <= fine;

indice = indice + passo)

iterazione;

• Oppure se ci sono più istruzioni da eseguire:

{//blocco di istruzioni

}

24

Struttura iterativa

• Nella sezione di inizializzazione si può anche inserire la definizione della variabile, che risulta “visibile” solo all’interno della struttura.

int n = 10;

for (int i = 1; i <= n; i = i+2)

cout<<i<<endl;

• L’indicazione dell’incremento della variabile i

appartiene all’intestazione della struttura e non deve più essere scritta all’interno della iterazione.

Struttura iterativa

• In entrambe queste strutture (while e for) la condizione viene verificata all’inizio: entrambi questi cicli possono non essere mai eseguiti.

• Nel ciclo for l’incremento della variabile i che governa il ciclo viene fatto alla fine della iterazione:

• i=1, verifica condizione (i <= n): è vera, iterazione, incremento di i che diventa 3; verifica condizione: è vera, iterazione, … , incremento di i che diventa 11; verifica condizione: è falsa; il ciclo termina.

Errori di programmazione

Errori di programmazione

• Quando scriviamo un programma possiamo introdurre degli errori.

• Gli errori che possiamo fare sono di due tipi:

• Errori che il compilatore evidenzia, errori di sintassi.

• Errori che si verificano quando il programma esegue le istruzioni, errori logici ed errori in esecuzione (il programma viene interrotto).

25

Errori compilazione

• Abbiamo visto alcuni errori che il compilatore segnala.

• Il compilatore segnala:

• il nome della funzione in cui si verifica l’errore

• il numero della riga in cui tale errore si verifica

• il tipo di errore rilevato.

• Questi errori sono (abbastanza) facili da correggere perché c’è un “suggerimento” da parte del compilatore.

Errori logici

• Consideriamo il seguente codice#include <iostream>

using namespace std;

int main () {// stampa un saluto

cout<<"viao a tutti "<<endl;

return 0;

}

• Questo errore non viene segnalato dal compilatore, che non può sapere che cosa il programmatore abbia intenzione di voler scrivere:• la compilazione va a buon fine ma il risultato è

errato perché viene prodotto un output diverso dal previsto.

Errori logici

• Sono molto più insidiosi degli errori di sintassi:

• il programma viene compilato correttamente, ma non fa quello che dovrebbe fare.

• L’eliminazione degli errori logici richiede molta attenzione:

• si esegue il programma su vari casi e si osservano con attenzione i risultati prodotti; i casi di prova devono essere “certi” ossia si deve conoscere il risultato.