La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

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

Presentazioni simili


Presentazione sul tema: "Programmazione Mod A - Cap 2 - prof. Burattini 1."— Transcript della presentazione:

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

2 2 Lenunciato di assegnazione La forma sintattica di questo enunciato è la seguente: variabile = espressione In esecuzione il computer valuta lespressione ed il suo valore è assegnato alla variabile (detta variabile di assegnazione). Il simbolo speciale = è detto operatore di assegnazione. stato del programma: linsieme dei valori delle variabili del programma Lesecuzione 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 loccorrenza 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é unassegnazione restituisce il risultato di unespressione (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.

3 Programmazione Mod A - Cap 2 - prof. Burattini 3 Se però le variabili presenti nellespressione sono tutte variabili numeriche è ammessa la conversione implicita dal tipo della espressione al tipo della variabile se questultima è di tipo più generale. REGOLA La variabile di assegnazione deve essere dello stesso tipo del valore dellespressione

4 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. r1r2n1n2 inizialmente???? n1 = 1 ? ? 1? n2=3??13 n2 = n1*n2+1??14 r1 = ?14 r2 = r r1 = n2*r r2 = 2 +n Nel penultimo caso cè compatibilità perché nel calcolare il prodotto, n2 è trasformato in float; Nellultimo caso 2+n1, che è di tipo int viene trasformato in float per conversione implicita..

5 Programmazione Mod A - Cap 2 - prof. Burattini 5 FUNZIONE MATEMATICAFUNZIONE C++OSSERVAZIONI x0 e restituisce un valore 0 double sqrt (double x) ;radice quadrata di x sen x con x numero realedouble sin (double x) ;seno di x cos x con x numero realedouble cos (double x) ;coseno di x tg x con x numero realedouble tan (double x) ;tangente di x arcsen x con x nellintervallo [-1 ;+1]double asin (double x) ;arcoseno di x arccos x con x nellintervallo [-1 ;+1]double acos (double x) ;arcocoseno do x arctg x con x numero realedouble atan (double x) ;arcotangente di x con x numero realedouble exp (double x) ;e elevato ad x con x numero realedouble pow10 (double x) ;10 elevato ad x ln x con x numero reale positivodouble log (double x) ;logaritmo naturale di x

6 Programmazione Mod A - Cap 2 - prof. Burattini 6 log x con x numero reale positivov log10 (double x) ;logaritmo di base 10 di x con x numero realedouble fabs (double x) ;valore assoluto di x Calcolo dellipotenusa 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 esponentedouble frexp (double x, int* esp) ;Scompone il numero x nella mantissa e nellesponente

7 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++ Lespressione si scrive con listruzione di assegnazione seguente: y = (a* pow(x,3) - 3*pow(x,5)) /(2*a*b) oppure y = (a* pow(x,3) - 3*pow(x,5)) /2/a/b Lespressione si scrive con listruzione di assegnazione seguente: z = sqrt(pow(x,4) – 3) /fabs(x-1)

8 Programmazione Mod A - Cap 2 - prof. Burattini 8 ESERCIZI A- Tradurre in C++ le seguenti formule. Scrivere in C++ i seguenti programmi. 1) CALCOLO DEL PERIMETRO DI UN TRIANGOLO Calcolare il perimetro di un triangolo qualsiasi supponendo assegnati i tre lati a,b,c. 2) CALCOLO IPOTENUSA DI UN TRIANGOLO RETTANGOLO Calcolare l'ipotenusa di un triangolo rettangolo supponendo assegnati i due cateti b e c. (Ricordiamo che lipotenusa si esprime in C++ come hypot(b,c) : si deve includere anche il file ). 3) CALCOLO MEDIA E SOMMA DEI VALORI ASSOLUTI DEGLI SCARTI Inserire in ingresso tre numeri reali a, b, c e applicare le formule (M=Media, S=scarto medio:

9 Programmazione Mod A - Cap 2 - prof. Burattini 9 4) SOMMARE DUE NUMERI INTERI Dare in input i numeri interi a e b e far scrivere il risultato. Provare i valori a = , b= oppure a = b = ) STAMPARE I VALORI DI ALCUNE FUNZIONI Applicare 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 char dire cosa stampa il computer allorché esegue le seguenti istruzioni: n1= 11; n2=3 ; cout<

10 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 loperazione in modo molto compatto. Consideriamo lo schema seguente Variabile = Variabile operazione Espressione che traduce esempi come i = i + 1 i = i – 1 somma = somma + i p = p * h questi 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).

11 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. La distinzione è particolarmente significativa quando gli operatori di incremento e decremento sono usati in espressioni che coinvolgono altri operatori.

12 Programmazione Mod A - Cap 2 - prof. Burattini 12 Consideriamo lespressione 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. Lespressione 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 loperatore di decremento. Teniamo presente che gli operatori di incremento e decremento hanno la precedenza sugli altri operatori.

13 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

14 Programmazione Mod A - Cap 2 - prof. Burattini 14 ISTRUZIONI DI CONTROLLO O SELEZIONE IF E IF……… ELSE Unistruzione può essere semplice o composta. Le istruzioni di scrittura e lettura, le dichiarazioni di costanti e di variabili, lenunciato di assegnazione sono istruzioni semplici. Una istruzione composta è una successione di istruzioni semplici racchiusa tra parentesi graffe. Unistruzione di selezione consente di deviare il flusso dei comandi.

15 Programmazione Mod A - Cap 2 - prof. Burattini 15 Il programma sul calcolo dellarea del cerchio è un flusso di istruzioni eseguite sequenzialmente; come dovremmo modificare il programma che calcola larea del cerchio se qualcuno inserisse un raggio negativo? Potremmo dire qualcosa del genere SE raggio>0 ALLORA esegui i calcoli ALTRIMENTI Stampa(il raggio non può essere negativo) In C++ possiamo adoperare listruzione if …. else: if (espressione booleana) istruzione1 else istruzione2 altre istruzioni //Calcola la circonferenza #include using namespace std; int main () { const float pi=3.1415; float circonf,raggio; cout << "Inserisci Raggio="; cin >> raggio; circonf=2*pi*raggio; cout << "circonferenza =" <

16 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 dellalgoritmo in C++: if (a

17 Programmazione Mod A - Cap 2 - prof. Burattini 17 Esempio: Dati due numeri qualsiasi a, b risolvere lequazione di primo grado: ax +b = 0. Lalgoritmo: 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 (a 0) x -b/a stampa(x) else stampa(messaggio) { float x,a,b; cout<>a; cout>b if (a!=0) // parentesi graffa necessaria perché listruzione è composta { x= - b/a; cout<

18 Programmazione Mod A - Cap 2 - prof. Burattini 18 Esempio: programma per il calcolo dellarea del cerchio che accetta solo input di numeri positivi. // Calcola Area del cerchio #include 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 ="<

19 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) = a 2 – b 2 b*(a – b) =(a+b)*(a – b) b = (a+b) 1=2 Vediamo cosa accade quando non conosciamo bene la matematica assurdo

20 Programmazione Mod A - Cap 2 - prof. Burattini 20 ERRORI tipici su IF ……. ELSE ……… Se scriviamo if (N>0); S = A + N; listruzione 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 dellistruzione composta, { e}; ad esempio: ERRATA CORRETTA if (N>0) S = A + N; Cout<<è unaddizione; else S = A * N; if (N>0) { S = A + N; Cout<<è unaddizione; } else S = A * N;

21 Programmazione Mod A - Cap 2 - prof. Burattini 21 Lerrore più comune è quello di confondere lassegnazione con il confronto. Se scriviamo if (N=0) S = A + N; listruzione 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 lespressione e poi la variabile (cosa non consentita con lassegnazione): NON si può scrivere if (0=N) perché il computer segnala un errore, mentre è consentito scrivere if (0==N)

22 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 ); 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'.

23 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. Lalgoritmo sarà allora: ripeti 10 volte: leggi(raggio) circonferenza 2* *raggio stampa(circonferenza) In via del tutto generale lutente dice al programma quante circonferenze deve calcolare come segue: leggi(n) ripeti n volte: leggi(raggio) circonferenza 2* *raggio stampa(circonferenza)

24 Programmazione Mod A - Cap 2 - prof. Burattini 24 Per codificare questo algoritmo si usa listruzione for Esempio in C++ //Calcola n volte la circonferenza di un cerchio #include using namespace std; int main () { const float pi=3.1415; float circonf, raggio; int n; cout<>n; for (int i=1;i<=n;++i) { cout << endl<< Inserisci il raggio: "; cin >> raggio; circonf=2*pi*raggio cout << "circonferenza ="<

25 Programmazione Mod A - Cap 2 - prof. Burattini 25 Forma sintattica del ciclo for: for (inizializzazione;espressione booleana;espressione di incremento) istruzione altre 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. Nellesempio 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. Lordine di valutazione è il seguente: 1.inizializzazione della variabile di ciclo 2.si valuta lespressione 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 lespressione di incremento, la variabile di ciclo si modifica, e si ripete il passo 2. for (int i=1;i<=n;++i) { …………… }

26 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 stampare 4x1=4 4x2=8 4x3=12 ……………………………..4x10=40 Lalgoritmo 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<

27 Programmazione Mod A - Cap 2 - prof. Burattini 27 Tornando al problema del calcolo della circonferenza si vuole consentire allutente 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*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.

28 Programmazione Mod A - Cap 2 - prof. Burattini 28 La traduzione dellalgoritmo in un programma C++ è: #include ; using namespace std; int main() { const float pi=3.1415; float circonf,raggio; int n; cout<>raggio; while (raggio != 0) { circonf=2*pi*raggio; cout << circonferenza = <>raggio; } system("pause"); }

29 Programmazione Mod A - Cap 2 - prof. Burattini 29 La sintassi del while è molto semplice così come la sua semantica while (espressione booleana) istruzione finchè lespressone booleana è vera ripeti istruzione. Il corpo del loop può essere unistruzione 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

30 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 lespressione 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

31 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 è =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 = 1 contatore=2 somma = (1) + 2 contatore=3 somma = (1+2) + 3 contatore=4 somma = (1+2+3) + 4 e così via I 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; allingresso del ciclo il contatore è inizializzato ad 1 e la somma a zero.

32 Programmazione Mod A - Cap 2 - prof. Burattini 32 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 lalgoritmo si modifica come segue: ALGORITMO 2 – SOMMA DEI PRIMI N INTERI 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

33 Programmazione Mod A - Cap 2 - prof. Burattini 33 Programma in C++ #include using namespace std; // calcola la somma dei primi N numeri int main () { int somma, contatore, N; cout << Calcola la somma dei primi N numeri<> N; contatore=0; somma=0; while (contatore

34 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/ =11*10/2= =8*7/2=28 (n+1)*n/

35 Programmazione Mod A - Cap 2 - prof. Burattini 35 ALGORITMO PER IL MASSIMO COMUN DIVISORE (MCD) Si trovi il MCD tra i numeri e 1843 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

36 Programmazione Mod A - Cap 2 - prof. Burattini 36 Ricerca Fattori Primi 93217=31 x 31 x 97

37 Programmazione Mod A - Cap 2 - prof. Burattini 37 Ricerca Fattori Primi 1843=19 x 97

38 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 e 1843 è Numero di passi totale = = 53

39 Programmazione Mod A - Cap 2 - prof. Burattini 39 N R R R R M MCD= R ALGORITMO DI EUCLIDE

40 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 1Si divide m per n 2Se il resto è zero allora n è il MCD tra m e n. 3Se il resto è diverso da zero torna al primo passo scambiando m con n e n con r (cioè dividi n per r)

41 Programmazione Mod A - Cap 2 - prof. Burattini 41 ESEMPIO MCD tra e 1843

42 Programmazione Mod A - Cap 2 - prof. Burattini 42 Analizziamo il Massimo Comun Divisore tra due interi con lalgoritmo di Euclide. Riscriviamo lalgoritmo 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 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.

43 Programmazione Mod A - Cap 2 - prof. Burattini 43 Il programma in C++ è dato da: #include using namespace std; main () { int a,b,r; cout << Calcolo del M C D<> a>>b; r=a % b; cout<0) { a=b; b=r; r= a % b; } cout << b <

44 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 laltro positivo, uno positivo ed uno nullo. Apportare al programma le modifiche necessarie affinché dia sempre risposte coerenti.

45 Programmazione Mod A - Cap 2 - prof. Burattini 45 Conversione di tipo (casting implicito). Durante lesecuzione 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 unoperazione 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= espressione Il compilatore forza il tipo del valore dellespressione in modo da fargli assumere il tipo della variabile che appare a sinistra. Se il tipo dellespressione ha una precisione minore del tipo della variabile, come in Variabile-double = espressione-float allora non cè alcun problema; se, invece, accade il contrario, come in Variabile-float = espressione-double potrebbero nascere due tipi di problemi: 1 - il risultato dellespressione-double contiene un numero di cifre che il tipo float non gestisce, con una grave perdita di precisione; 2 - il risultato dellespressione-double supera il massimo valore rappresentabile come float: in tal caso non è prevedibile in generale il comportamento del programma.

46 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 nellespressione. 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 T1 T2 x2; // x2 è di tipo T2 possiamo convertire la variabile x2 al tipo T1 scrivendo x1 = (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 loperatore (T1) alla variabile x2. Essa è soggetta alle regole di precedenza degli operatori. Nel C++ si consiglia, per la conversione esplicita, di usare loperatore di conversione static_cast mediante la notazione x1 = static_cast (x2)

47 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<

48 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=0 if conta0 stampa(xm) … if x1<>0 stampa(x1) Per risolvere un problema molto semplice occorrerebbe scrivere un programma lunghissimo anche nel caso che n fosse dellordine delle centinaia.

49 Programmazione Mod A - Cap 2 - prof. Burattini 49 Quando si devono manipolare molti elementi dello stesso tipo, tutti i linguaggi imperativi permettono luso 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 dellarray. 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 dellarray e il valore dellespressione 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 dellarray deve essere calcolata durante la fase di compilazione e pertanto in espressione possono essere presenti solo valori letterali o costanti.

50 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 dellindirizzo corrispondente alla variabile b che identifica larray, sommato allindice posto tra parentesi quadre; i loro valori (right value) sono rispettivamente 1.5, 0.4 e 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 dellarray si adopera loperatore di subscript [].

51 Programmazione Mod A - Cap 2 - prof. Burattini 51 Gli array dellesempio 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 lesecuzione di un programma il vettore Vet dellesempio contenga esattamente i 10 elementi sotto rappresentati: Vet In generale con Vet[espressione] si accede allelemento del vettore il cui indice è il valore dellespressione. 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 dellarray. Se il valore dellespressione è maggiore o uguale alla dimensione dellarray si ha un errore logico

52 Programmazione Mod A - Cap 2 - prof. Burattini 52 Listruzione Vet[10]=2 non ha senso poiché si attribuisce un valore ad una variabile che non rappresenta una componente dellarray Vet. Lo stesso può accadere se lespressione risulta maggiore o uguale al numero di elementi effettivamente presenti nellarray. E pertanto compito del programmatore assicurarsi che situazioni di questo genere non si verifichino perché esse possono dar luogo ad errori difficilmente rintracciabili.

53 Programmazione Mod A - Cap 2 - prof. Burattini 53 //Esempio riempimento e stampa inversa di un array #include using namespace std; int main () { int const m=300; int a[m],i, n; cout<<"Quanti elementi? "; cin>>n; cout<<"Dammi "<>a[i]; cout<<"Lista inversa "<=0;i--) cout<

54 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

55 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

56 Programmazione Mod A - Cap 2 - prof. Burattini 56 Array di caratteri e stringhe Il 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é allarray di caratteri venga aggiunto il carattere nullo \0, cioè lelemento 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.

57 Programmazione Mod A - Cap 2 - prof. Burattini 57 È possibile inizializzare una stringa anche in un altro modo. Scrivendo char s[]=ciao; In questo modo si crea una stringa di 5 caratteri s[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 caratteri char Str[21]=Nel mezzo del cammin.

58 Programmazione Mod A - Cap 2 - prof. Burattini 58 Usando cin per la gestione dellinput, 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 listruzione 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 linput termina solo digitando il tasto Invio.

59 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, nome Esempio: se lutente 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 nome Alla fine aggiungi il carattere nullo Stampa 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è dallindice 5 in poi.

60 Programmazione Mod A - Cap 2 - prof. Burattini 60 #include 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<

61 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

62 Programmazione Mod A - Cap 2 - prof. Burattini 62 /*QUESTO PROGRAMMA ESEGUE LA SOMMA DEI NUMERI PARI E DISPARI CON DIVERSI ALGORITMI*/ #include 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<

63 Programmazione Mod A - Cap 2 - prof. Burattini 63 // PROCESSO LENTO cout<<" PROCESSO LENTO "<

64 Programmazione Mod A - Cap 2 - prof. Burattini 64 // PROCESSO MEDIO cout<<" PROCESSO MEDIO "<

65 Programmazione Mod A - Cap 2 - prof. Burattini 65 Numero pari Np= N *(N+4) 4 Nd= N *(N-2) 4 Numero dispari Np= N Nd= (N+1) 2 4

66 Programmazione Mod A - Cap 2 - prof. Burattini 66 // PROCESSO VELOCE cout<<" PROCESSO VELOCE "<

67 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;

68 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; // lidentificatore riposo non essendo nella lista è errato, domani=ris; // è unuguaglianza 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 lultimo); 4 – allinterno della macchina il dato viene trattato come un intero.

69 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)!

70 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 delluguaglianza 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.

71 Programmazione Mod A - Cap 2 - prof. Burattini 71 ESEMPIO #include using namespace std; int main() { enum giorno {lunedi=1, martedi, mercoledi, giovedi, venerdi, sabato, domenica}; giorno oggi; cout<<"Giorni della settimana"<

72 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 =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 specificare inizializzazione: contatore di ciclo inizializzato a zero, i = 0, e somma = 0; condizione di uscita: lultimo 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 listruzione (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 lintero 3, mentre (int) c – (int) 0 restituisce lintero rappresentato dal carattere c, se c è compreso tra 0 e 9.

73 Programmazione Mod A - Cap 2 - prof. Burattini 73 #include 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="<

74 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 precedente Se, per esempio, : s="abc3x casa2 y34zq" il programma deve restituire somma= =12 numero= =3246. */ eser2.10bis

75 Programmazione Mod A - Cap 2 - prof. Burattini 75 Typedef Listruzione typedef serve a dare un nuovo nome ad un tipo già esistente. Per esempio typedef unsigned int Uint; crea il tipo Uint che corrisponde allintero 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;

76 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 strumentiOpzioni di compilazione Generazioni di codice/ Ottimizzazione LinkerGenera 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.

77 Programmazione Mod A - Cap 2 - prof. Burattini 77

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

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

80 Programmazione Mod A - Cap 2 - prof. Burattini 80 /*QUESTO PROGRAMMA INSERITO DA TASTIERA UN NUMERO INTERO IN BASE 10 LO TRASFORMA IN BASE 2 (BINARIO) e poi in base 10*/ #include using namespace std; int main () { int A,B,i=0; int const N=16; float R[N],bas=2; float decimale; cout<>A; cout<0) { B=(A%2); A=(A/2); ++i; R[N-i]=B; } for (int j=1;j<=(N-1);j++) cout<


Scaricare ppt "Programmazione Mod A - Cap 2 - prof. Burattini 1."

Presentazioni simili


Annunci Google