80
Programmazione Mod A - Ca p 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini 1

Embed Size (px)

Citation preview

Page 1: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

1

Page 2: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

2

L’enunciato di assegnazione

La forma sintattica di questo enunciato è la seguente:variabile = espressione

In esecuzione il computer valuta l’espressione ed il suo valore è assegnato alla variabile (detta variabile di assegnazione). Il simbolo speciale = è detto operatore di assegnazione.

stato del programma: l’insieme dei valori delle variabili del programma

L’esecuzione di un enunciato di assegnazione provoca il cambiamento dello stato del programma.

Si consideri la sequenza di istruzioni: n = 4; n = n+1; con la seconda istruzione il valore di n cambia da 4 a 5. Si osservi come l’occorrenza di n a sinistra di = si riferisce al suo indirizzo o left value mentre quella a destra di = si riferisce al suo contenuto o right value. Poiché un’assegnazione restituisce il risultato di un’espressione (il valore del calcolo eseguito a destra viene assegnato alla variabile che appare a sinistra) è necessario che il tipo della espressione sia compatibile con il tipo della variabile di assegnazione.

Page 3: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

3

Se però le variabili presenti nell’espressione sono tutte variabili numeriche è ammessa la conversione implicita dal tipo della espressione al tipo della variabile se quest’ultima è di tipo più generale.

REGOLA La variabile di assegnazione deve essere dello stesso tipo del

valore dell’espressione

Page 4: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

4

Supponiamo che le variabili r1 e r2 siano state dichiarate di tipo float mentre n1 e n2 siano di tipo int e che non siano state ancora inizializzate. Vediamo come la successione di enunciati di assegnazione varia il loro valore . r1 r2 n1 n2

inizialmente ? ? ? ?

n1 = 1 ? ? 1 ?

n2=3 ? ? 1 3

n2 = n1*n2+1 ? ? 1 4

r1 = 5.2 5.2 ? 1 4

r2 = r1 + 2.2 5.2 7.4 1 4

r1 = n2*r1 20.8 7.4 1 4

r2 = 2 +n1 20.8 3.0 1 4

Nel penultimo caso c’è compatibilità perché nel calcolare il prodotto, n2 è trasformato in float;Nell’ultimo caso 2+n1, che è di tipo int viene trasformato in float per conversione implicita..

Page 5: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

5

FUNZIONE MATEMATICA FUNZIONE C++ OSSERVAZIONI

x≥0 e restituisce un valore ≥0

double sqrt (double x) ; radice quadrata di x

sen x con x numero reale double sin (double x) ; seno di x

cos x con x numero reale double cos (double x) ; coseno di x

tg x con x numero reale double tan (double x) ; tangente di x

arcsen x con x nell’intervallo [-1 ;+1] double asin (double x) ; arcoseno di x

arccos x con x nell’intervallo [-1 ;+1] double acos (double x) ; arcocoseno do x

arctg x con x numero reale double atan (double x) ; arcotangente di x

con x numero reale double exp (double x) ; e elevato ad x

con x numero reale double pow10 (double x) ; 10 elevato ad x

ln x con x numero reale positivo double log (double x) ; logaritmo naturale di x

xex10

x

Page 6: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

6

x

xy

arctg

yx

log x con x numero reale positivo v log10 (double x) ; logaritmo di base 10 di x

con x numero reale double fabs (double x) ; valore assoluto di x

Calcolo dell’ipotenusa di un triangolo rettangolo

double hypot (double x, double y) ; Ipotenusa di un triangolo rettangolo i cui cateti hanno lunghezza x ed y

double atan2 (double y, double x) ; Arcotangente di y/x. il valore restituito è compreso fra –pigreco e + pigreco estremi compresi

con x , y numeri reali

double pow (double x, double y) ; x elevato ad y

Calcola mantissa ed esponente double frexp (double x, int* esp) ; Scompone il numero x nella mantissa e nell’esponente

Page 7: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

7

Tutte le funzioni in C++ restituiscono dei valori double invece che float; il tipo double rappresenta ancora un numero decimale ma con un maggior grado di precisione. Le due espressioni matematiche seguenti sono tradotte in C++

1

3

2

3

4

53

x

xz

ab

xaxy

L’espressione si scrive con l’istruzione di assegnazione seguente:y = (a* pow(x,3) - 3*pow(x,5)) /(2*a*b) oppurey = (a* pow(x,3) - 3*pow(x,5)) /2/a/b

L’espressione si scrive con l’istruzione di assegnazione seguente:z = sqrt(pow(x,4) – 3) /fabs(x-1)

Page 8: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

8

ESERCIZIA- Tradurre in C++ le seguenti formule.

Scrivere in C++ i seguenti programmi.1) CALCOLO DEL PERIMETRO DI UN TRIANGOLOCalcolare il perimetro di un triangolo qualsiasi supponendo assegnati i tre lati a,b,c .2) CALCOLO IPOTENUSA DI UN TRIANGOLO RETTANGOLOCalcolare l'ipotenusa di un triangolo rettangolo supponendo assegnati i due cateti b e c .(Ricordiamo che l’ipotenusa si esprime in C++ come hypot(b,c) : si deve includere anche il file <cmath>).3) CALCOLO MEDIA E SOMMA DEI VALORI ASSOLUTI DEGLI SCARTIInserire in ingresso tre numeri reali a, b, c e applicare le formule (M=Media, S=scarto medio:

)ln()6;)5;

)5(

3)4

;2

)()3;

2)2;

2)1

22

44

223

34

23

ba

bah

babca

bca

fbxa

xxy

xx

cbxa

senacbA

cbap

3

cbaM

3

cMbMaMS

Page 9: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

9

4) SOMMARE DUE NUMERI INTERIDare in input i numeri interi a e b e far scrivere il risultato.Provare i valori a = 2 000000000 , b= 1 000000000 oppure a = b = 2 000000000.

5) STAMPARE I VALORI DI ALCUNE FUNZIONIApplicare a due numeri reali a e b le due funzioni logaritmo, la funzione esponenziale e la funzione arcotangente e far scrivere il risultato (porre attenzione ai valori da assegnare!).

6) Se n1 ed n2 sono variabili di tipo int , r una variabile di tipo float e c una variabile di tipo chardire cosa stampa il computer allorché esegue le seguenti istruzioni:n1= 11;n2=3 ;cout<<n1*n2;c=’H’;n2=n1%n2 ;cout<<c<<endl<<n2;r=n1/n2 ;n1=n1/n2;cout<<n1<<endl<<r;

Scrivere un programma completo che esegua questa sequenza di istruzioni.

Page 10: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

10

Operatori di incremento e decremento

Tra gli operatori aritmetici forniti dal C++ ve ne sono alcuni che consentono di scrivere l’operazione in modo molto compatto. Consideriamo lo schema seguente

Variabile = Variabile operazione Espressioneche traduce esempi come

i = i + 1 i = i – 1 somma = somma + i p = p * hquesti possono essere scritti in modo compatto, rispettivamente, come

i++ i-- somma += i p *= h

In particolare i primi due termini i = i + 1 ed i = i – 1, sono detti rispettivamente operatori di incremento e decremento.

Tali operatori hanno due forme:

una forma postfissa (i++, i--) e la forma prefissa (++i , --i).

Page 11: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

11

Le due forme non sono equivalenti.

Il significato di i++ è

“usa il valore di i e dopo incrementa la variabile i”

mentre il significato di ++i è

“incrementa la variabile i e dopo usa il valore di i”.

Questa distinzione non è importante quando li utilizziamo singolarmente. Ladistinzione è particolarmente significativa quando gli operatori di incremento edecremento sono usati in espressioni che coinvolgono altri operatori.

Page 12: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

12

Consideriamo l’espressione

somma += i++

poiché la forma è postfissa, i passi che vengono eseguiti sono:

1. si prende il valore di i e si calcola somma +=i, cioè somma = somma + i;2. si incrementa il valore di i.

L’espressione somma += ++i

scritta nella forma prefissa produce i seguenti risultati

1. si incrementa il valore di i;2. si prende il valore di i e si calcola somma +=i, cioè somma = somma + i;

Le stesse considerazioni valgono per l’operatore di decremento. Teniamo presente che gli operatori di incremento e decremento hanno la precedenza sugli altri operatori.

Page 13: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

13

ESERCIZIO

a) k = 8 e i = ++k quanto valgono k ed i ?

b) k = 8 e i = k++ quanto valgono k ed i ?

eser2.0a

Page 14: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

14

ISTRUZIONI DI CONTROLLO O SELEZIONEIF E IF……… ELSE

Un’istruzione può essere semplice o composta.

Le istruzioni di scrittura e lettura, le dichiarazioni di costanti e di variabili, l’enunciato di assegnazione sono istruzioni semplici.

Una istruzione composta è una successione di istruzioni semplici racchiusa tra parentesi graffe.

Un’istruzione di selezione consente di deviare il flusso dei comandi.

Page 15: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

15

Il programma sul calcolo dell’area del cerchio è un flusso di istruzioni eseguite sequenzialmente; come dovremmo modificare il programma che calcola l’area del cerchio se qualcuno inserisse un raggio negativo?Potremmo dire qualcosa del genereSE raggio>0 ALLORA esegui i calcoli ALTRIMENTI Stampa(“il raggio non può essere negativo”) In C++ possiamo adoperare l’istruzione if …. else:

if (espressione booleana) istruzione1else istruzione2altre istruzioni

//Calcola la circonferenza #include <iostream>#include <cstdlib>using namespace std; int main () { const float pi=3.1415; float circonf,raggio; cout << "Inserisci Raggio="; cin >> raggio; circonf=2*pi*raggio; cout << "circonferenza =" <<circonf<<endl; system("pause");}

L’espressione booleana viene valutata: •se risulta vera viene eseguita istruzione1; •se invece risulta falsa viene eseguita istruzione2.• In ogni caso, dopo aver eseguito la istruzione1 oppure la istruzione2, il programma esegue le “altre istruzioni”.

Page 16: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

16

Esempio 1: Massimo tra due numeri a e b

Se a è minore di b allora il massimo è b, altrimenti è a.

Scrittura dell’algoritmo in C++:

if (a<b) cout<<”MASSIMO=”<<b;

else cout<<”MASSIMO=”<<a ;

Supponiamo che a=15 e b=20; quando il computer esegue questa istruzione scriverà “Massimo=20”; se invece a=30 e b=10 scriverà “Massimo=30”.

Una forma semplificata della istruzione if else è l’istruzione if:if (espressione booleana) istruzionealtre istruzioni

In questo caso se l’espressione booleana risulta vera allora l’istruzione viene eseguita, se invece risulta falsa non viene eseguita. In ogni caso successivamente saranno eseguite le “altre istruzioni”.

Page 17: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

17

Esempio: Dati due numeri qualsiasi a, b risolvere l’equazione di primo grado: ax +b = 0.

L’algoritmo: leggi(a,b)stampa(-b/a)

non è corretto. Infatti il problema dice che a può essere un numero qualsiasi e, se a fosse zero, si avrebbe un errore a run time poiché la divisione non è definita quando il divisore è zero. In questo caso occorrerà dunque inviare un opportuno messaggio. Un algoritmo corretto è:

leggi(a,b)if (a0) x -b/a stampa(x)else stampa(messaggio)

{ float x,a,b; cout<<’inserire i coefficienti di una equazione di primo grado’; cout<<”a(!0)= “; cin>>a; cout<”’b”=’; cin>>b if (a!=0) // parentesi graffa necessaria perché l’istruzione è composta

{ x= -b/a; cout<<”soluzione x =”<<x<<endl; } // fine istruzione composta relative alla condizione (a!=0) else cout<<”l’equazione non è risolvibile essendo a=0”; }

//La condizione va posta tra parentesi tonde.

eser2.1

Page 18: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

18

Esempio: programma per il calcolo dell’area del cerchio che accetta solo input di numeri positivi. // Calcola Area del cerchio#include <iostream>#include <cstdlib>using namespace std;int main () { const float pi=3.1415; float area, raggio; cout << "Inserisci Raggio="; cin>>raggio; if (raggio>0) { area=raggio*raggio*pi; cout << "Area ="<<area <<endl; } else cout<< “Il raggio non può essere negativo “<<endl; system(“pause”);}

eser2.2

Page 19: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

19

a=1

b=a

b*a=a*a

b*a - b*b = a*a - b*b

b*(a – b) = a2 – b2

b*(a – b) =(a+b)*(a – b)

b = (a+b)

1=2

Vediamo cosa accade quando non conosciamo bene la matematica

assurdo

Page 20: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

20

ERRORI tipici su IF ……. ELSE ………Se scriviamo

if (N>0); S = A + N;

l’istruzione S = A + N verrà eseguita in qualsiasi caso in quanto il simbolo ‘;’ chiude l’ if.Analogamente si ha nel caso seguente:

if (N>0) S = A + N;

else ; S = A * N;

Un altro errore tipico è dato dalla mancanza dei delimitatori dell’istruzione composta, ‘{‘ e ‘}’; ad esempio:

ERRATA CORRETTA if (N>0) S = A + N; Cout<<”è un’addizione”;else S = A * N;

if (N>0) { S = A + N; Cout<<”è un’addizione”;}else S = A * N;

Page 21: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

21

L’errore più comune è quello di confondere l’assegnazione con il confronto. Se scriviamo

if (N=0) S = A + N;

l’istruzione S = A + N verrà sempre eseguita perché il computer porrà il valore 0 nella variabile N.

Ricordiamo che per eseguire il confronto tra due termini è necessario il simbolo ‘= =’.

Per evitare questo errore si può scrivere prima l’espressione e poi la variabile (cosa non consentita con l’assegnazione):

NON si può scrivereif (0=N)

perché il computer segnala un errore, mentre è consentito scrivereif (0==N)

Page 22: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

22

ESERCIZI

1) DETERMINARE SE UN NUMERO E' INTERO.Per risolvere il problema pensiamo di confrontare il numero letto con la sua parte intera: se i due valori sono uguali allora il numero e' intero, altrimenti non lo e'. (La parte intera si calcola con floor(N): si deve includere anche il file <cmath>);

2) DETERMINARE SE UN NUMERO INTERO E' PARI.Per risolvere il problema pensiamo di calcolare il resto modulo 2; se tale resto è zero allora il numero e' pari altrimenti non lo e'.

Page 23: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

23

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)

Page 24: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

24

Per codificare questo algoritmo si usa l’istruzione for

Esempio in C++

//Calcola n volte la circonferenza di un cerchio#include <iostream> #include <cstdlib> using namespace std; int main () { const float pi=3.1415; float circonf, raggio; int n; cout<<”Dimmi quanti raggi hai: “; cin>>n; for (int i=1;i<=n;++i) { cout << endl<< “Inserisci il raggio: "; cin >> raggio; circonf=2*pi*raggio cout << "circonferenza ="<<circonf<<endl; } system("pause"); }

Page 25: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

25

Forma sintattica del ciclo for:for (inizializzazione;espressione booleana;espressione di incremento)

istruzionealtre istruzioni

L’ istruzione che segue la parentesi destra ‘) ‘ può essere una istruzione semplice o composta e rappresenta il corpo del ciclo for.

Nella inizializzazione, alla variabile del ciclo for si assegna un valore iniziale. Nel nostro caso la variabile di ciclo i viene contemporaneamente definita e inizializzata ad 1.

L’ espressione booleana controlla il ciclo: solo se è vera il corpo del ciclo può essere eseguito, prende perciò il nome di condizione di ingresso al ciclo, la sua negata prende il nome di condizione di uscita. Nell’esempio la condizione di uscita è i>n.

La terza componente espressione è usata per modificare il valore della variabile di ciclo. Nel nostro esempio semplicemente si incrementa i di 1.

L’ordine di valutazione è il seguente:1. inizializzazione della variabile di ciclo2. si valuta l’espressione booleana e, se vera,

si esegue espressione, cioè il corpo del ciclo,altrimenti il ciclo si interrompe e si passa alle “altre istruzioni”.

3. si valuta l’espressione di incremento, la variabile di ciclo si modifica, e si ripete il passo 2.

for (int i=1;i<=n;++i) {……………

}

Page 26: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

26

Esempio.

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

leggi(numero)for (i1;i<=10;++i)

stampa(numero*i)Il corrispondente codice C++ è dato da:

cin>>numerofor (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.

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

Page 27: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

27

Tornando al problema del calcolo della circonferenza si vuole consentire all’utente di calcolare un numero imprecisato cinconferenze 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*raggiostampa(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.

Page 28: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

28

La traduzione dell’algoritmo in un programma C++ è:

#include <iostream>;#include <cstdlib>;using namespace std;

int main() {const float pi=3.1415;float circonf,raggio; int n;

cout<<”Dammi il raggio: “;cin>>raggio;while (raggio != 0) {

circonf=2*pi*raggio;cout << “circonferenza =” <<circonf<<endl;cout<<”Dammi il raggio: “;cin>>raggio;

}system("pause");

}

Page 29: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

29

La sintassi del while è molto semplice così come la sua semanticawhile (espressione booleana) istruzione

finchè l’espressone booleana è vera ripeti istruzione.

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.

Page 30: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

30

Siano a e b due numeri interi (tipo integer) 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). Quale sarà il valore di a che verrà stampato alla fine del ciclo?

a=5;b=10;while (a<b) { a++; b--;}cout<<”a=”<<a<<endl;

Dopo l’inizializzazione con a=5 e b=10 entriamo nel ciclo while perché la condizione (a<b) è vera; al primo passo otteniamo a=6 e b=9 in quanto a è incrementato di 1 e b è decrementato di 1. Si ritorna alla condizione di controllo del ciclo, (a<b), e poiché 6<9, si esegue un altro ciclo, all’uscita del quale a=7 e b=8. Si ritorna ancora al controllo (a <b), si verifica che, essendo 7<8, si deve eseguire ancora il corpo del ciclo; dopo questo terzo passaggio la condizione (a <b) è falsa per cui si salta il ciclo e si esegue l’istruzione subito dopo, cout<<”a =”<<a<<endl, per cui il computer scriverà sul video a=8

passo a binizio 5 10 N. 1 6 9 N. 2 7 8 N. 3 8 7

eser2.3

Page 31: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

31

Esempio.Assegnato un numero intero N, sommare tutti gli interi compresi tra 1 ed N.Se N=4 allora la somma è 1+2+3+4=10.Analizziamo il problema: abbiamo bisogno di una variabile contatore che contenga volta per volta i valori 1, 2, 3, ……., N e di una variabile somma che contenga le somme parziali; cioècontatore=1 somma = 1contatore=2 somma = (1) + 2contatore=3 somma = (1+2) + 3contatore=4 somma = (1+2+3) + 4 e così viaI valori che abbiamo posto tra parentesi rappresentano la somma ottenuta al passo precedente; questa situazione può essere descritta con la formula

somma=somma+contatore; o anche somma+=contatore;

La condizione di ingresso può essere espressa con (contatore<=N).

Dobbiamo solo controllare cosa accade quando si entra la prima volta nel ciclo; all’ingresso del ciclo il contatore è inizializzato ad 1 e la somma a zero.

Page 32: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

32

ALGORITMO 1 – SOMMA DEI PRIMI N INTERIinizializza contatore a 1 e somma a 0while 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 – SOMMA DEI PRIMI N INTERIinizializza contatore e somma a 0while contatore < N ripeti incrementa il contatore di 1 incrementa il valore della variabile somma con il contenuto di contatore

Page 33: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

33

Programma in C++ #include <iostream>#include <cstdlib>using namespace std;// calcola la somma dei primi N numeriint main () { int somma, contatore, N; cout << “Calcola la somma dei primi N numeri”<<endl; cout << “Inserisci N=”; cin >> N; contatore=0; somma=0; while (contatore<N) { contatore++; somma+=contatore } cout << "Somma =" << somma <<endl; system("pause");} eser2.4

Page 34: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

34

Karl Friedrich Gauss, nato nel 1777 a Brunswick in Germania, ad appena 10 anni, quando un suo insegnante di matematica, per levarselo dai piedi, gli impose di fare la somma dei numeri interi da 1 a 100, dopo pochi minuti gli diede la soluzione ragionando come segue.

(n+1)*n/2

1 2 3 4 5 6 7 8 9 10+ + + + + + + + +

1 2 3 4 5

10 9 8 7 6

11 11 11 11 11 =11*10/2=55

+ + + + +

1 2 3 4 5 6 7

1 2 3

7 6 5 4

7 7 7 7 =8*7/2=28 (n+1)*n/2

+ + + + + +

+ + +

Page 35: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

35

ALGORITMO PER IL MASSIMO COMUN DIVISORE(MCD)

Si trovi il MCD tra i numeri 93217

e1843

•Si cercano i fattori primi del primo numero•Si cercano i fattori primi del secondo numero•Si cercano i fattori primi comuni a entrambi i numeri

Page 36: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

36

RicercaFattoriPrimi

NUMERI PRIMI 93217

n° PASSI

2 46608,5 13 31072,33 25 18643,4 37 13316,71 4

11 8474,273 513 7170,538 617 5483,353 719 4906,158 823 4052,913 929 3214,379 10 3007 97

31 3007 11 31 97 1 31 3,129032 137 2,621622 241 2,365854 343 2,255814 447 2,06383 553 1,830189 659 1,644068 761 1,590164 867 1,447761 971 1,366197 1073 1,328767 1179 1,227848 1283 1,168675 1389 1,089888 14

TOTALE OPERAZIONI 27 97 1 15

93217=31 x 31 x 97

Page 37: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

37

NUMERI PRIMI 1843

n° PASSI

2 921,5 13 614,333 25 368,6 37 263,286 4

11 167,545 513 141,769 617 108,412 719 97 8 97

19 5,1053 123 4,2174 229 3,3448 331 3,129 437 2,6216 541 2,3659 643 2,2558 747 2,0638 853 1,8302 959 1,6441 1061 1,5902 1167 1,4478 1271 1,3662 1373 1,3288 1479 1,2278 1583 1,1687 1689 1,0899 1797 1 18

TOTALE OPERAZIONI 26

RicercaFattoriPrimi

1843=19 x 97

Page 38: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

38

Massimo Comune Divisore

Fattori Primi di 93217 = 31*31*97

Fattori Primi di 1843 = 19*97

Il MCD tra 93217 e 1843 è

Numero di passi totale = 27+26 = 53

Page 39: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

39

NR

RR’ R’

M

MCD=R’

ALGORITMO DI EUCLIDE

Page 40: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

40

ALGORITMO DI EUCLIDE PER IL MASSIMO COMUN DIVISORE

(300 A.C.)

Siano m ed n due numeri naturali e supponiamo sia m>n

•1 Si divide m per n

•2 Se il resto è zero allora n è il MCD tra m e n.

•3 Se il resto è diverso da zero torna al primo passo scambiando m con n e n con r (cioè dividi n per r)

Page 41: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

41

ESEMPIO

MCD tra 93217 e 1843

m n m/n r N° passi93217 1843 50 1067 1

1843 1067 1 776 21067 776 1 291 3

776 291 2 194 4291 194 1 97 5194 97 2 0 6

Page 42: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

42

Analizziamo il Massimo Comun Divisore tra due interi con l’algoritmo di Euclide.Riscriviamo l’algoritmo in pseudo-codice.

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 bScrivi 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.

Page 43: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

43

Il programma in C++ è dato da:

#include <iostream>#include <cstdlib>using namespace std;main () { int a,b,r; cout << “Calcolo del M C D”<<endl; cout << “Assegnare a e b :”; cin >> a>>b; r=a % b; cout<<”MCD di “<<a<<” e “<<b<<” = “; while (r>0) { a=b; b=r; r= a % b; } cout << b <<endl; system(“pause”); } eser2.5

Page 44: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

44

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.

Page 45: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

45

Conversione di tipo (casting implicito).Durante l’esecuzione di un programma esistono delle situazioni in cui viene

cambiato il tipo di dato:1. quando un valore di un tipo viene assegnato alla variabile di un altro;2. quando un’operazione contiene due elementi di tipo diverso (per esempio la somma di un intero con un reale);Questo fatto può provocare degli errori difficilmente individuabili. Ad esempio:

variabile= espressioneIl compilatore forza il tipo del valore dell’espressione in modo da fargli assumere il

tipo della variabile che appare a sinistra. Se il tipo dell’espressione ha una precisione minore del tipo della variabile, come in

Variabile-double = espressione-floatallora non c’è alcun problema; se, invece, accade il contrario, come in

Variabile-float = espressione-doublepotrebbero nascere due tipi di problemi:1 - il risultato dell’espressione-double contiene un numero di cifre che il tipo float

non gestisce, con una grave perdita di precisione;2 - il risultato dell’espressione-double supera il massimo valore rappresentabile

come float: in tal caso non è prevedibile in generale il comportamento del programma.

Page 46: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

46

Casting esplicito

Nel caso di operazioni tra tipi differenti, la prima regola generale è che tutti i tipi che sono immagazzinati con pochi byte, sono “promossi” al tipo più ampio che appare nell’espressione. Le altre regole sono piuttosto complicate ma, comunque, possono essere superate con il casting esplicito.

Supponiamo di avere due variabili di tipo T1 e T2:T1 x1; // x1 è di tipo T1T2 x2; // x2 è di tipo T2

possiamo convertire la variabile x2 al tipo T1 scrivendox1 = (T1) x2 o x1 = T1 (x2)

Tale notazione, presa totalmente dal linguaggio C, è detta conversione esplicita o casting esplicito, in quanto si “costringe” la variabile a cambiare tipo. La conversione esplicita è comunque un operatore: è come se applicassimo l’operatore (T1) alla variabile x2. Essa è soggetta alle regole di precedenza degli operatori.Nel C++ si consiglia, per la conversione esplicita, di usare l’operatore di conversione static_cast mediante la notazionex1 = static_cast <T1>(x2)

Page 47: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

47

Esempio

A titolo esemplificativo stampiamo i caratteri ASCII visibili (compresi tra 32 e 127)

int i=32;while (i<=127){ cout<< (char) i << “ ha codice “<< i<<endl; i++;}

dove notiamo che l’intero i viene convertito in modo esplicito a carattere.

eser casting

Page 48: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

48

Array monodimensionali

Supponiamo di voler scrivere un programma che, ricevuto in input un intero n ed n interi positivi, li stampi in ordine inverso. Ci troviamo di fronte al problema di non sapere a priori quante variabili dobbiamo definire. Un modo di aggirare questo problema consiste nel dichiarare un numero m di variabli x1,x2,…xm con m sufficientemente grande. Il seguente algoritmo allora, risolve il problema per ogni n<=m:

leggi(n)conta=0if conta<n leggi(x1) else x1=0conta=conta+1if conta<n leggi(x2)else x2=0…conta=conta +1if conta<n leggi(xm) else xm=0if xm<>0 stampa(xm)…if x1<>0 stampa(x1)

Per risolvere un problema molto semplice occorrerebbe scrivere un programma lunghissimo anche nel caso che n fosse dell’ordine delle centinaia.

Page 49: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

49

Quando si devono manipolare molti elementi dello stesso tipo, tutti i linguaggi imperativi permettono l’uso della struttura dati array. Un array è un insieme ordinato di elementi dello stesso tipo.Gli elementi di un array sono detti componenti ed il loro tipo è chiamato componente-tipo dell’array. Essi sono immagazzinati in posizioni consecutive di memoria.Nel caso di array monodimensionali la dichiarazione di una variabile di tipo array è la seguente:

Tipo-componente identificatore[espressione ]

Dove Tipo-componente è il tipo dei componenti, identificatore è il nome dell’array e il valore dell’espressione racchiusa tra parentesi quadre ne rappresenta la dimensione cioè il numero massimo di componenti che può essere contenuto in un array. Un array (o vettore) può anche essere inizializzato, nel qual caso la dimensione può essere calcolata implicitamente dal compilatore.

Si noti che la dimensione dell’array deve essere calcolata durante la fase di compilazione e pertanto in espressione possono essere presenti solo valori letterali o costanti.

Page 50: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

50

ESEMPI

float b[]={1.5,0.4,15}; dove b è un array di dimensione 3 contenente i 3 numeri reali racchiusi tra parentesi tonde; la dimensione del vettore b è calcolata implicitamente durante la inizializzazione e b[0], b[1] e b[2] sono tre variabili reali, il loro indirizzo (left value) è dato dalla somma dell’indirizzo corrispondente alla variabile b che identifica l’array, sommato all’indice posto tra parentesi quadre; i loro valori (right value) sono rispettivamente 1.5, 0.4 e 15.0.

const int max=30;int Vet[10], vet[max]; Vet è un array che può contenere al massimo 10 interi, vet al massimo 30 interi float a[12]; a è un array composto al massimo da 12 numeri reali.

Per poter accedere ai vari elementi dell’array si adopera l’operatore di subscript [].

Page 51: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

51

Gli array dell’esempio sono detti monodimensionali perché un solo operatore di subscript, (un solo indice) permette di individuare i suoi componenti.Supponiamo che ad un certo istante durante l’esecuzione di un programma il vettore Vet dell’esempio contenga esattamente i 10 elementi sotto rappresentati:

Vet

In generale con Vet[espressione] si accede all’elemento del vettore il cui indice è il valore dell’espressione.Pertanto il contenuto di Vet [2] è 8, quello di Vet [6] è 12, mentre se il contenuto di i è 4 allora il contenuto di Vet [i* 2] è 0, quello di Vet [i + 1] è 15.

In generale dunque se la variabile A è stata definita come un array, A[espressione] è a tutti gli effetti una variabile il cui tipo è quello dei componenti dell’array.Se il valore dell’espressione è maggiore o uguale alla dimensione dell’array si ha un errore logico.

0 1 2 3 4 5 6 7 8 9

4 -2 8 5 -6 15 12 -4 0 23

Page 52: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

52

L’istruzione Vet[10]=2 non ha senso poiché si attribuisce un valore ad una variabile che non rappresenta una componente dell’array Vet.

Lo stesso può accadere se l’espressione risulta maggiore o uguale al numero di elementi effettivamente presenti nell’array.

E’ pertanto compito del programmatore assicurarsi che situazioni di questo genere non si verifichino perché esse possono dar luogo ad errori difficilmente rintracciabili.

Page 53: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

53

//Esempio riempimento e stampa inversa di un array

#include <iostream>#include <cstdlib>using namespace std;int main () { int const m=300; int a[m],i, n; cout<<"Quanti elementi? "; cin>>n; cout<<"Dammi "<<n<<" elementi di seguito separati

da uno spazio "<<endl; for (i=0;i<n;i++) cin>>a[i];

cout<<"Lista inversa "<<endl; for (i=n-1; i>=0;i--) cout<<a[i]<<endl;}

eser2.6

Page 54: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

54

Si osservi inoltre che se A e B sono due array è errato scrivere A=B.

Per copiare un array in un altro occorre scrivere un for che copi ogni elemento di B in A. Cioè:

for(int i=1;i<n;i++)A[I]=B[I];

Una variabile di tipo array non può comparire da sola in un enunciato di assegnazione o in una espressione booleana.

Page 55: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

55

ESERCIZI

Assegnato un vettore a di n interi, verificare che tutti i suoi elementi sono positivi.

Assegnato un vettore a di n interi, verificare che tutti i suoi elementi sono nulli

Scrivere un programma che scriva tutti i numeri interi multipli di 3 e non di 7 inclusi tra 15 e 100.Utilizzare il ciclo while

Scrivere un programma che calcoli la somma di tutti i numeri interi pari inclusi tra 5 e 100 escludendo i multipli di 3 e 5.Utilizzare il ciclo while

Scrivere un programma che esegua la somma di tutti i numeri interi inseriti da tastiera finché tale somma non superi il valore di 150; dalla somma vanno esclusi i numeri che contengono la cifra 1.

Scrivere un programma che esegua il prodotto di tutti i numeri interi inseriti da tastiera finché tale prodotto non superi il valore di 15000; dal prodotto vanno esclusi i numeri che sono multipli di 3.

eser2.7b

Page 56: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

56

Array di caratteri e stringheIl tipo char ha dimensione di un byte e contiene il numero di codice ASCII che gli corrisponde. Un letterale di tipo carattere deve essere sempre racchiuso tra virgolette semplici, ad esempio: ‘a’.Oltre agli array di numeri interi o reali, possiamo definire anche gli array di caratteri; per esempio

char s[]={‘c’, ‘i’, ‘a’, ‘o’}dove s è un array di caratteri formato da 4 elementi s[0]=’c’; s[1]=’i’; s[2]=’a’; s[3]=’o’

Una stringa è un insieme di caratteri. Anche un array può essere visto come una stringa, purché all’array di caratteri venga aggiunto il carattere nullo ‘\0’, cioè l’elemento che ha codice ASCII uguale a 0. Quindi,

char s[]={‘c’, ‘i’, ‘a’, ‘o’, ‘\0’}per cui s è un array di caratteri costituito da 5 elementi.

Per gestire un array di caratteri come stringa non è necessario conoscere a priori la sua lunghezza in quanto è sufficiente scandire la stringa fino al simbolo ‘\0’.

Page 57: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

57

È possibile inizializzare una stringa anche in un altro modo. Scrivendochar s[]=”ciao”;

In questo modo si crea una stringa di 5 caratteris[0]=’c’; s[1]=’i’; s[2]=’a’; s[3]=’o’; s[4]=’\0’;che viene vista come un array di caratteri il cui ultimo elemento è ’\0’.

Se poniamo Str=”Nel mezzo del cammin”’, essa è una stringa lunga 20 caratteri, dove

Str[0] contiene il carattere ‘N’, Str[1] il carattere ‘e’, ……, Str[19] il carattere ‘n’, Str[20] contiene il carattere nullo ‘\0’

per cui la variabile Str dovrà essere dichiarata come un array di 21 caratterichar Str[21]=”Nel mezzo del cammin”’.

Page 58: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

58

Usando cin per la gestione dell’input, abbiamo che la lettura di ciascuna variabile termina quando incontra o il carattere spazio (la barra spaziatrice) o la tabulazione (tasto Tab) o il fine linea (tasto Invio).

Quindi non è possibile digitare una frase completa come stringa perché quando incontra uno spazio il computer non accetta altri caratteri. Per ovviare a questo inconveniente esiste l’istruzione

cin.getline(s, n)

dove s è una variabile stringa ed n è un numero intero che rappresenta il numero massimo di caratteri che possono essere letti; in tal caso s può contenere anche spazi in quanto l’input termina solo digitando il tasto Invio.

Page 59: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

59

ESEMPIO

Scrivere un programma che, dato un nome in input, costruisca una stringa contenente il testo

ciao, nomeEsempio: se l’utente digita il nome Antonio, il programma deve restituire la stringa str contenente il testo

ciao, Antonio

I passi da seguire sono i seguenti:

Poni la scritta “ciao,” nella variabile str;Leggi(nome);Aggiungi tutti i carattere del nomeAlla fine aggiungi il carattere nulloStampa la stringa str;

Ci serviamo di un indice j che scorre tutti i caratteri della stringa nome assegnata in input finché non raggiunge il carattere nullo; ognuno di questi caratteri deve essere aggiunto alla stringa str dopo “ciao,”, cioè dall’indice 5 in poi.

Page 60: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

60

#include <iostream>#include <cstdlib>using namespace std;int main() { char nome[20]; char str[30]="ciao,";// str contiene 5 caratteri + ‘\0’ int j=0; cout<<"nome: "; cin>>nome; while (nome[j]!='\0') // finché la stringa non termina str[j+5]=nome[j++];// aggiungi il carattere dalla quinta posizione

str[j+5]='\0'; // aggiungi il carattere di fine stringa cout<<str<<endl;

system("pause");}

eser2.8

Page 61: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

61

ESERCIZI

Assegnata una stringa s, scrivere un programma che conteggi i caratteri ‘a’ in essa contenuti.

Assegnata una stringa s, ed un intero n minore della lunghezza della stringa, scrivere un programma che stampi tutti i caratteri compresi tra n e la lunghezza della stringa.

Assegnata una stringa s, e due interi m<n minori della lunghezza della stringa, scrivere un programma che stampi la sottostringa che va da m ad n. Esempio: s=’ciao mamma’ ed m=3, n=4 il programma deve stampare la stringa ao ma

Scrivere un programma che, assegnata in input una stringa s del tipo

aaa@bbb stampi su videonome: aaaindirizzo: bbb

eser2.81

eser2.82

Page 62: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

62

/*QUESTO PROGRAMMA ESEGUE LA SOMMA DEI NUMERI PARI E DISPARI CON DIVERSI ALGORITMI*/

#include <iostream> #include <cstdlib>#include <math.h>using namespace std;

int main () { double N,Q; double Sp,Sd,pari=0,dispari=0,contatore=0,j=0;cout<<" DAMMI IL NUMERO N ";cin>>N;cout<<" La somma totale dei numeri vale "<<(N+1)*(N)/2<<endl;

Page 63: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

63

// PROCESSO LENTO cout<<" PROCESSO LENTO "<<endl; for (int i=0; i<=N; i+=2){ contatore+=i;}cout<<" Dato il numero "<<N<<endl;cout<<" La somma dei numeri pari da 1 a "<<N<<" vale "<<contatore<<endl;

for (int i=1; i<=N; i+=2){ j+=i;}cout<<" La somma dei numeri dispari da 1 a "<<N<<" vale "<<j<<endl;cout<<" Somma totale= "<<contatore+j<<endl;system("pause");

Page 64: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

64

// PROCESSO MEDIOcout<<" PROCESSO MEDIO "<<endl; for (int i=1; i<=N; ++i){ if (i%2==0) { pari+=i; } else { dispari+=i; }}cout<<" Dato il numero "<<N<<endl;cout<<" La somma dei numeri pari da 1 a "<<N<<" vale "<<pari<<endl;cout<<" La somma dei numeri dispari da 1 a "<<N<<" vale "<<dispari<<endl;cout<<" Somma totale= "<<pari+dispari<<endl;system("pause");

Page 65: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

65

Numero pari

Np= N *(N+4)4

Nd= N *(N-2)4

Numero dispari

Np= N2-14

Nd= (N+1)2

4

Page 66: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

66

// PROCESSO VELOCEcout<<" PROCESSO VELOCE "<<endl; Q=floor(N/2);if (N==2*Q) { Sp=(N)*(N+4)/4; Sd=(N)*(N-2)/4; }else {Sp=(N*N)/4; Sd=(N+1)*(N+1)/4; } cout<<" Dato il numero "<<N<<endl;cout<<" La somma dei numeri pari da 1 a "<<N<<" vale "<<Sp<<endl;cout<<" La somma dei numeri dispari da 1 a "<<N<<" vale "<<Sd<<endl;cout<<" Somma totale= "<<Sp+Sd<<endl; system("pause");}

Page 67: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

67

Tipi enumerativi

Introduciamo un nuovo tipo detto tipo enumerativo.

Esso viene introdotto con la parola chiave enum secondo lo schema seguente:

enum Nome-Tipo { lista dei valori accettabili }

Esempi:

enum giorno {lunedi, martedi, mercoledi, giovedi,venerdi,sabato,domenica}enum risposta {si, no, nonso}

I due tipi nuovi, giorno e risposta, possono essere utilizzati nella dichiarazione delle variabili:

giorno oggi, domani;risposta ris;

Page 68: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

68

Il tipo enumerativo è caratterizzato da tre aspetti essenziali:

1 - è un tipo definito dal programmatore che può essere utilizzato nella dichiarazione di una variabile;

2 – la lista dei valori accettabili è un insieme di identificatori: tali identificatori rappresentano i soli valori che le variabili di quel tipo possono assumere; non è possibile assegnare alle variabili di quel tipo altri valori diversi da quelli prescritti:

domani=riposo; // l’identificatore riposo non essendo nella lista è errato, domani=ris; // è un’uguaglianza tra due tipi diversi e quindi è errato

3 – è un tipo ordinale nel senso che si può parlare di un precedente (tranne il primo) e di un successivo (tranne l’ultimo);

4 – all’interno della macchina il dato viene trattato come un intero.

Page 69: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

69

Il C++ associa ad ogni identificatore definito nella lista un numero intero che parte da zero; perciò, lunedì corrisponde a 0, martedì ad 1, e così via (non sono accettate le vocali accentate). Ha sicuramente senso scrivere

oggi <= domani

il compilatore interpreterà il risultato sostituendo i rispettivi valori alle variabili e restituirà un valore vero o falso.Supponiamo invece di scrivere

domani < = ris

In fase di compilazione il compilatore dovrebbe dare un errore. Invece, il migliore dei compilatori fornisce un errore di avvertimento (warning)!

Page 70: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

70

Consideriamo ancora la possibilità di utilizzare un costrutto iterativo per evidenziare tutti i giorni della settimana:

for (oggi=lunedì; oggi <= domenica; oggi++){ …….istruzioni….. }

il compilatore evidenzia un errore!

Infatti, poiché oggi ++ è equivalente a oggi = oggi+1

il compilatore forza il valore oggi a destra dell’uguaglianza a diventare un intero, per poi assegnare alla variabile oggi (che appare alla sinistra) ancora un intero; in questo modo la variabile oggi perde il suo significato iniziale per diventare un intero.

Si può ovviare a questo inconveniente forzando con un casting al tipo giorno il risultato.

for (oggi=lunedì; oggi <= domenica; oggi=giorno(oggi+1))

il valore di oggi+1 è forzato ad assumere un valore di tipo giorno.

Page 71: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

71

ESEMPIO

#include <iostream>#include <stdlib.h>using namespace std;int main() { enum giorno {lunedi=1, martedi, mercoledi, giovedi, venerdi, sabato, domenica}; giorno oggi; cout<<"Giorni della settimana"<<endl; for (oggi=lunedi; oggi<=domenica; oggi=giorno(oggi+1)) { cout<<oggi<<" "; if (oggi<=venerdi) cout<<" giorno lavorativo"<<endl; else if (oggi==sabato) cout<<" giorno semifestivo"<<endl; else cout<<" giorno festivo"<<endl; } system("pause");}

eser2.9

Page 72: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

72

Esercizio. Assegnata una stringa s contenente anche delle cifre, sommare tutte le cifre e fornire il valore totale di tale somma.

Esempio, : s=”abc3x casa2 y34zq” il programma deve restituire 3+2+3+4=12.Pseudo codice:

assegnare la stringa s;scandire ogni carattere c delle stringa finché non termina; (while)verificare se è compreso tra 0 e 9

se lo è incrementare la somma con il valore corrispondente della cifra;passare al carattere successivo;stampare la somma totale.

Nel ciclo while dobbiamo specificareinizializzazione: contatore di ciclo inizializzato a zero, i = 0, e somma = 0;condizione di uscita: l’ultimo carattere letto è la sequenza di escape \0 c == ‘\0’; la

condizione di esecuzione del ciclo è la sua negazione, c != ‘\0’;corpo del ciclo: se il carattere è una cifra aggiungerla a somma; incrementare in ogni

caso il contatore i;Osserviamo che l’istruzione (int) c effettua un casting esplicito da carattere a

numero: ciò che si ottiene è il codice ASCII di c; se sottraiamo tale valore al codice ASCII del carattere che rappresenta lo zero, otteniamo proprio il valore numerico della cifra. In altre parole,

(int) ‘3’ – (int) ‘0’ restituisce l’intero 3, mentre (int) c – (int) ‘0’ restituisce l’intero rappresentato dal carattere c, se c è compreso tra 0 e 9.

Page 73: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

73

#include <iostream>#include <cstdlib>using namespace std;int main() { char s[100]; int i, somma; cout<<"Stringa="; cin.get(s,100); i=0; somma=0; while (s[i]!= '\0') { if ((s[i]>='0') && (s[i]<='9')) somma+=(int)s[i]-(int)'0'; i++; } cout<<"somma="<<somma<<endl; system("pause");}

eser2.10

Page 74: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

74

Esercizio

Assegnata una stringa s contenente anche delle cifre, sommare tutte le cifre e fornire il valore totale di tale somma.Trasformare le cifre in un numero e sommarlo al valore precedenteSe, per esempio, : s="abc3x casa2 y34zq" il programma deve restituire somma=3+2+3+4=12numero=3234+12=3246.*/

eser2.10bis

Page 75: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

75

TypedefL’istruzione typedef serve a dare un nuovo nome ad un tipo già esistente. Per esempio

typedef unsigned int Uint;crea il tipo Uint che corrisponde all’intero senza segno, mentre la definizione

typedef int Integer;crea un altro tipo con le stesse caratteristiche del tipo int.

La ragione più importante per cui si utilizza typedef è la portabilità del software: può accadere che una macchina utilizzi in modo particolare le variabili reali, per cui i tipi float, double e long double sono gestiti in modalità diversa dallo standard. In tal caso è sufficiente definire con typedef nuovi tipi di reali in corrispondenza alle esigenze. Per esempio, supponiamo di dover eseguire dei calcoli su due diverse macchine; sulla prima è implementata la versione standard del tipo double, mentre sulla seconda macchina, supportando un tipo double che non ci soddisfa, riteniamo necessario utilizzare il tipo long double.Per scrivere un solo programma per le due macchine definiamo un tipo reale con

typedef double reale;che utilizzeremo nelle dichiarazioni del programma.Per rendere funzionale il programma anche sulla seconda macchina è sufficiente cambiare soltanto la definizione di typedef

typedef long double reale;

Page 76: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

76

Debug con Dev-Cpp

Il debug del compilatore ci aiuta a seguire passo-passo una variabile per esaminarne il valore.Analizziamo passo-passo il programma che calcola la somma dei primi N numeri, descritto precedentemente servendoci del debug gdb inserito nel compilatore. Per assicurarci che il debugger gdb sia attivo andiamo su

strumenti→Opzioni di compilazione→ Generazioni di codice/ Ottimizzazione →Linker→Genera le informazioni di debug, scegliamo yes e compiliamo il programma per assicurarci che vada tutto bene (il file exe ottenuto è almeno raddoppiato in ampiezza).

Clicchiamo col mouse alla sinistra del while (il rigo cambierà colore): ciò sta ad indicare che in quel punto il programma si fermerà per consentirci di eseguirlo passo-passo;

Clicchiamo sulla icona Debug (in basso); apparirà la situazione in figura.

Page 77: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

77

Page 78: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

78

Il programma è in esecuzione e noi vogliamo analizzare il valore delle due variabili i e Somma che variano durante il calcolo;

clicchiamo su Nuova Osservazione ed inseriamo la variabile i alla richiesta Stampa Nome Variabile; vedremo apparire il suo valore nella finestra di sinistra (dove avremo scelto ancora la modalità di Debug).

Ripetiamo la stessa operazione con la variabile somma; anche somma andrà nella stessa finestra.

Premendo più volte il tasto Step Succ possiamo vedere passo-passo sia le istruzioni eseguite (in genere di colore blu) che i valori assunti dalle variabili.

Per poter rintracciare gli errori (i bug) nei programmi è fondamentale appropriarsi di questa metodologia; il consiglio è di utilizzare inizialmente il debug anche quando i programmi funzionano verificando che le variabili assumano i valori che ci aspettiamo.

Page 79: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

79

Esercizi.

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) ?

Page 80: Programmazione Mod A - Cap 2 - prof. Burattini 1

Programmazione Mod A - Cap 2 - prof. Burattini

80

/*QUESTO PROGRAMMA INSERITO DA TASTIERA UN NUMERO INTERO IN BASE 10LO TRASFORMA IN BASE 2 (BINARIO) e poi in base 10*/

#include <iostream>#include <cstdlib>#include <cmath>using namespace std;

int main () { int A,B,i=0; int const N=16; float R[N],bas=2; float decimale; cout<<endl<<"Inserire il numero in base 10 da trasformare in base 2."<<endl<<endl; cin>>A; cout<<endl; cout<<"Il numero in binario e' "<<endl; for (int j=0;j<=(N-1);j++) R[j]=0; cout<<endl;

cout<<"Il numero in decimale e' "<<endl; decimale=0; for (int j=0;j<=(N-1);j++) { decimale+=(R[N-j-1]*pow(bas,j)); } cout<<decimale<<endl; system("pause"); }

// Ciclo WHILE per il calcolo e la stampa delle cifre del binario. while (A>0) { B=(A%2); A=(A/2); ++i; R[N-i]=B; } for (int j=1;j<=(N-1);j++) cout<<R[j]; cout<<" "<<endl;