INDICE C++
1.01 - Alcuni semplici programmi in C++
- Ingresso e uscita di informazioni (1-2-3-4)
- Istruzioni condizionali (5-6-7-8)
- Il ciclo for (9-10)
- Il ciclo while (11-12A-12B-12C)
- Gli array (13-14-15-16-17)
- Le funzioni (18-19-20-21-22-23-24-25-26)
1.02 -
1.03 -
1.04 -
1.05 -
1.01 - Alcuni semplici programmi in C++ 1. QUESTO PROGRAMMA MOLTIPLICA 7 PER UN NUMERO QUALSIASI FORNITO IN LETTURA ATTRAVERSO LA TASTIERA E SOMMA 10 AL RISULTATO DEL PRODOTTO #include <stdio.h> /* Questa riga indica che una o più istruzioni che compariranno in seguito, si possono trovare nel file stdio.h */ #include <stdlib.h> main() { int x,y; printf(" QUESTO PROGRAMMA MOLTIPLICA 7 PER UN NUMERO QUALSIASI"); printf("\n FORNITO IN LETTURA ATTRAVERSO LA TASTIERA E SOMMA 10 AL"); printf("\n RISULTATO DEL PRODOTTO."); printf("\n\n\n\n dammi un numero x a tua scelta"); printf(" e poi premi il tasto 2. QUESTO PROGRAMMA MOLTIPLICA DUE NUMERI QUALSIASI a ED x FORNITI IN LETTURA ATTRAVERSO LA TASTIERA E SOMMA AL RISULTATO DEL PRODOTTO UN TERZO NUMERO b FORNITO IN LETTURA ATTRAVERSO LA TASTIERA #include <stdio.h> #include <stdlib.h> main() { int a,b,x,y; printf("\n\n\n\n a="); scanf("%d",&a); printf("\n x="); scanf("%d",&x); printf("\n b="); scanf("%d",&b); y=a*x+b; printf("\n %dx%d+%d=%d\n\n\n\n",a,x,b,y); system ("PAUSE"); return 0; } 3. QUESTO PROGRAMMA SCAMBIA I VALORI DI DUE VARIABILI IN MODO SBAGLIATO #include <stdio.h> #include <stdlib.h> main() { int a,b; printf("\n valori di a e b prima dello scambio"); printf( "\n\n a="); scanf("%d",&a); printf( "\n b="); scanf("%d",&b); a=b;b=a; // ECCO DOVE STA LO SBAGLIO → Sotto la spiegazione printf("\n valori di a e b dopo lo scambio"); printf("\n\n a=%d b=%d\n\n",a,b); system ("PAUSE"); return 0; } Supponiamo di avere assegnato a=1 e b=2; lo scambio dovrebbe avvenire mediante le due istruzioni a=b;b=a; tuttavia la prima delle due, cioè a=b, ha per effetto che il valore di b (cioè 2) viene trascritto in a e quindi a questo punto sia a che b hanno il valore 2 e quando viene eseguita la seconda istruzione b=a in b viene trascritto il valore attuale di a cioè 2; il risultato finale sarà che comparirà sullo schermo la scritta a=2 b=2 che non è assolutamente ciò che avremmo voluto vedervi comparire. A nulla vale tentare di scambiare l’ordine delle due istruzioni, modificando la riga in: a=b;b=a; 4. QUESTO PROGRAMMA SCAMBIA I VALORI DI DUE VARIABILI IN MODO CORRETTO #include <stdio.h> #include <stdlib.h> main() { int a,b,appo; printf("\n valori di a e b prima dello scambio"); printf( "\n\n a="); scanf("%d",&a); printf( "\n b="); scanf("%d",&b); appo=a;a=b;b=appo; printf("\n valori di a e b dopo lo scambio"); printf("\n\n a=%d b=%d\n\n",a,b); system ("PAUSE"); return 0; } Istruzioni condizionali 5. QUESTO PROGRAMMA DETERMINA IL MAGGIORE FRA DUE NUMERI a E b #include <stdio.h> #include <stdlib.h> main() { int a,b,max; printf("\n\n primo numero a="); scanf("%d",&a); // LEGGO LA VARIABILE a printf("\n secondo numero b="); scanf("%d",&b); // LEGGO LA VARIABILE b max=a; if (b>max) max=b; // VEDI SOTTO LA SPIEGAZIONE DI QUESTE ISTRUZIONI printf("\n\n il massimo fra %d e %d è: %d",a,b,max); // LA "è" NON VIENE STAMPATA POICHE' NON CODIFICATA system ("PAUSE"); return 0; } La strategia per decidere quale è più grande fra a e b è la seguente: inizialmente mettiamo in max il valore di a, dopo di che, se il valore di b è maggiore del valore di max (e quindi del valore di a) allora cambiamo il valore di max con il valore di b, altrimenti lasciamo le cose come stanno. Il risultato è che alla fine in max ci sarà sicuramente il più grande fra i valori di a e b. 6. QUESTO PROGRAMMA DETERMINA IL MAGGIORE FRA QUATTRO NUMERI a,b,c E d #include <stdio.h> #include <stdlib.h> main() { int a,b,c,d,max; printf("\n primo numero a="); scanf("%d",&a); printf("\n secondo numero b="); scanf("%d",&b); printf("\n terzo numero c="); scanf("%d",&c); printf("\n quarto numero d="); scanf("%d",&d); max=a; if (b>max) max=b;if (c>max) max=c; if (d>max) max=d; printf("\n il massimo fra %d,%d,%d e %d --> MAX: %d\n\n",a,b,c,d,max); system ("PAUSE"); return 0; } Creaiamo ora programma che calcola il discriminante di un polinomio (L'informatica applicata a problemi di matematica) In una equazione di secondo grado del tipo ax2+bx+c=0 con coefficienti reali a, b e c, possiede due radici reali distinte se il discriminante: D=b2-4ac è positivo, altrimenti possiede una unica radice reale se il discriminante è nullo e infine possiede due radici complesse coniugate se il discriminante è negativo. Ecco un semplice programma in cui sfruttiamo di nuovo il costrutto if per decidere se una data equazione di secondo grado possiede due radici reali distinte oppure no. 7. QUESTO PROGRAMMA LEGGE I COEFFICIENTI a,b,c DI UN POLINOMIO DI SECONDO GRADO, NE CALCOLA IL DISCRIMINANTE E, SE QUESTO E' POSITIVO, SEGNALA CHE ESISTONO DUE RADICI REALI DISTINTE #include <stdio.h> #include <stdlib.h> main() { float a,b,c,delta; // VARIABILI REALI printf( "\n primo coefficiente a="); scanf("%f",&a); // ESSENDO VARIABILi REALI USIAMO IL FORMATO %f printf( "\n secondo coefficiente b="); scanf("%f",&b); printf( "\n terzo coefficiente c="); scanf("%f",&c); printf("\n"); delta=b*b-4*a*c; if (delta>0) // CONDIZIONE 1 printf(" ci sono due radici reali distinte\n"); else if (delta==0) // CONDIZIONE 2, CON == POICHE' IL SIMBOLO =, IN C++ È UN OPERATORE DI ASSEGNAZIONE E NON UN SIMBOLO DI RELAZIONE printf(" c'è una unica radice reale\n"); else printf(" non ci sono radici reali\n"); system ("PAUSE"); return 0; } Non è difficile capire che, se noi annidiamo due volte il costrutto if-else dentro se stesso, potremo distinguere fra 4 casi, se lo annidiamo tre volte potremo distinguere fra 5 casi, e così via. Tuttavia il costrutto if-else ha l'inconveniente seguente: ogni volta che viene distinto un caso si può eseguire solamente una istruzione, che, negli esempi precedenti, è una istruzione printf mediante la quale viene stampato sullo schermo un messaggio. Sarebbe più logico procedere al calcolo completo delle radici; in altre parole, sarebbe meglio che il nostro programma facesse qualcosa del genere: se D>0 allora vengono calcolate e stampate sullo schermo le due radici reali x1=(-b+√D)/2a e x2=(-b-√D)/2a se D=0 allora viene calcolata e stampata sullo schermo la unica radice reale x1=-b/2a se D<0 allora vengono calcolate e stampate sullo schermo le due radici complesse coniugate x1=-b/2a+i(√-D/2a) e x2=-b/2a-i(-√D/2a) Per ottenere tutto ciò, è sufficiente racchiudere un certo numero di istruzioni fra le parentesi graffe aperta e chiusa; infatti in C++ ogni gruppo di istruzioni racchiuso fra { e } viene considerato come una unica istruzione; quindi in generale il costrutto if-else si può usare nella forma più generale: if (condizione1) {gruppo di istruzioni 1}; else if (condizione2) {gruppo di istruzioni 2}; else {gruppo di istruzioni 3}; 8. QUESTO PROGRAMMA LEGGE I COEFFICIENTI a,b,c DI UN POLINOMIO DI SECONDO GRADO, NE CALCOLA LE RADICI E LE STAMPA, SIA NEL CASO DI RADICI REALI CHE NEL CASO DI RADICI COMPLESSE #include <stdio.h> #include <math.h> #include <stdlib.h> main() { float a,b,c,delta,x1,x2,x,alfa,beta,aa,s; printf( "\n primo coefficiente a="); scanf("%f",&a); printf( "\n secondo coefficiente b="); scanf("%f",&b); printf( "\n terzo coefficiente c="); scanf("%f",&c); delta=b*b-4*a*c; aa=2*a; if (delta>0) { x1=(-b+sqrt(delta))/aa; x2=(-b-sqrt(delta))/aa; printf("\n ci sono due radici reali distinte \n"); printf("\n prima radice =%f \n",x1); printf("\n seconda radice =%f \n",x2); } else if (delta==0) { x=-b/aa; printf("\n c'è una unica radice reale =%f \n",x); } else { alfa=-b/aa; s=sqrt(-delta); beta=s/aa; printf("\n ci sono due radici complesse \n"); printf("\n prima radice =%f+i%f \n",alfa,beta); printf("\n seconda radice =%f-i%f \n",alfa,beta); } system ("PAUSE"); return 0; } Il ciclo for Supponiamo di voler scrivere un programma che legge un numero intero n e poi calcola e stampa il valore di n!; l’idea che useremo per ottenere n! è la seguente: prima di tutto introduciamo una variabile intera in cui andare a mettere il risultato e che chiameremo fatt e a cui assegneremo inizialmente il valore 1; dopo di che sarà sufficiente ripetere l’istruzione fatt=fatt*i; con la variabile intera i che assume successivamente tutti i valori da 1 ad n; in ultimo avremo in fatt il valore richiesto di n!, per cui basterà stampare fatt. Per scrivere un programma in C++ che effettui questa sequenza di operazioni, occorre introdurre delle nuove istruzioni, che sono dette istruzioni di ciclo. La più semplice istruzione di questo tipo è l’istruzione for che, nei casi più comuni, si presenta al modo seguente: for (istruzione1;condizione;istruzione2;) istruzione3; dove la istruzione1 (detta anche istruzione di inizializzazione) serve a fissare il valore iniziale della variabile intera con cui si compie il ciclo e nel caso del fattoriale dovrebbe quindi essere i=1; la condizione (detta anche condizione di iterazione) serve per decidere fino a quando il ciclo andrà ripetuto e nel caso del fattoriale dovrebbe quindi essere i<=n; la istruzione2 (detta anche istruzione di aggiornamento) serve ad aggiornare la variabile con cui si compie il ciclo e nel caso del fattoriale dovrebbe essere i=i+1; infine la istruzione3 è l’istruzione che deve essere ripetuta per tutto il ciclo e che nel caso del fattoriale sarà fatt=fatt*i. (Si osservi che anche in questo caso l’istruzione che deve essere ripetuta per tutto il ciclo, può essere sostituita da un gruppo di istruzioni a patto che vengano racchiuse fra le parentesi graffe). Ecco come si presenterà un programma che calcola il fattoriale di un intero assegnato col procedimento sopra descritto: 9. QUESTO PROGRAMMA CALCOLA E STAMPA IL FATTORIALE DI UN NUMERO n FORNITO IN LETTURA #include <stdio.h> #include <stdlib.h> main() { int i,n,fatt; printf("\n Inserire il num. per il calcolo del suo fattoriale --> n="); scanf("%d",&n); fatt=1; for (i=1;i<=n;i++) // i++ EQUIVALE A i=i+1 fatt=fatt*i; printf("\n Il fattoriale di %d=%d\n\n",n,fatt); // NEL 1° %d METTO IL VALORE DI n, NEL 2° QUELLO DI fatt system ("PAUSE"); return 0; } A questo proposito possiamo osservare subito che n! può essere calcolato sia facendo il prodotto dei numeri interi da 1 ad n, sia facendo il prodotto dei numeri interi da n ad 1; scritto in C++ sarà: 10. QUESTO PROGRAMMA CALCOLA E STAMPA IL FATTORIALE DI UN NUMERO n FORNITO IN LETTURA #include <stdio.h> #include <stdlib.h> main() { int i,n,fatt; printf("\n Inserire il num. per il calcolo del suo fattoriale --> n="); scanf("%d",&n); fatt=1; for(i=n;i>=1;i--) // i-- EQUIVALE A i=i-1 fatt=fatt*i; printf("\n Il fattoriale di %d=%d\n\n",n,fatt); // NEL 1° %d METTO IL VALORE DI n, NEL 2° QUELLO DI fatt system ("PAUSE"); return 0; } ATTENZIONE! se con il programma sopra mettiamo come fattoriale un numero n>=13 il programma sembra impazzire e fornisce valori assurdi (addirittura negativi talvolta). La ragione di questo strano comportamento è molto semplice: dal momento che la porzione di memoria riservata ad una variabile intera è “finita” (4 bytes), di conseguenza solo un numero finito di numeri interi vi sarà rappresentabile (per la precisione i numeri interi da -2147483648 fino a +2147483647). Poiché 13! vale 6227020800, esso eccede il limite di rappresentabilità degli interi; purtroppo il compilatore C++ non si accorge di ciò, infatti esso, quando raggiunge il valore limite +2147483647, prosegue semplicemente ricominciando dal numero -2147483648 (ecco perché si possono ottenere valori negativi!). Quando trattiamo con numeri interi, dobbiamo quindi sempre tenere conto di questa limitazione del compilatore C++ per evitare di trovarci in situazioni simili. Una soluzione che possiamo usare per calcolare il fattoriale di numeri interi più grandi di 12 è quella di definire la variabile fatt come float: Quindi nel programma sopra modificheremo le 2 righe di codice in: int i,n;float fatt; printf("=%f",fatt); Il ciclo while In tutti i programmi che abbiamo scritto finora per calcolare il fattoriale di un numero intero, abbiamo sempre usato l’istruzione for per eseguire il ciclo di calcolo; tuttavia questa non è l’unica istruzione del C++ che può essere usata per eseguire un ciclo. Un’altra istruzione che si usa per eseguire cicli è l’istruzione while, che ha la seguente sintassi: while (condizione) istruzione; Se condizione è vera, allora viene eseguita istruzione e successivamente si ritorna a valutare “condizione”, se questa è ancora vera si esegue di nuovo istruzione e così via fino a che condizione risulta falsa, nel qual caso si salta istruzione e si prosegue il programma. Un altra istruzione imparentata con while e che si può usare per eseguire cicli è l’istruzione do-while, che ha la seguente sintassi: do istruzione while (condizione); La differenza rispetto al semplicewhile è che con il dowhile prima si esegue istruzione e poi si valuta condizione e se questa è vera si torna ad eseguire istruzione altrimenti si prosegue nel programma; di conseguenza, con il do-while istruzione viene eseguita comunque almeno una volta, mentre con il semplice while istruzione potrebbe non essere mai eseguita (se cioè fin dalla prima volta condizione risultasse falsa). Naturalmente, sia per quanto riguarda while che do-while si potrà sostituire “istruzione” con un gruppo di istruzioni racchiudendole entro le parentesi graffe, per cui la forma più generale dell’istruzione while sarà: while (condizione) {gruppo di istruzioni}; mentre la forma più generale dell’istruzione do-while sarà: do {gruppo di istruzioni} while (condizione); Ecco qui di seguito due programmi con cui viene calcolato il fattoriale di un numero intero utilizzando appunto while e do-while. 11. QUESTO PROGRAMMA CALCOLA E STAMPA IL FATTORIALE DI UN NUMERO n FORNITO IN LETTURA #include <stdio.h> #include <stdlib.h> main() { int i,n;int fatt; printf("\n n="); scanf("%d",&n); fatt=1; i=1; while (i<=n) { fatt=fatt*i; i=i+1; } printf("\n fattoriale di %d=%d\n\n",n,fatt); system ("PAUSE"); return 0; } #include <stdio.h> #include <stdlib.h> main() { int i,n;int fatt; printf("\n n="); scanf("%d",&n); fatt=1;i=1; do { i++; fatt=fatt*i; }while (i<n); printf("\n fattoriale di %d=%d\n\n",n,fatt); system ("PAUSE"); return 0; } Si osservi che la “condizione” negli esempi sopra è diversa appunto perché nel primo caso si usa il while semplice e quindi bisogna richiedere la condizione i<=n, mentre nel secondo caso si usa il do-while e quindi bisogna richiedere la condizione i<n. Il trucco che abbiamo usato per calcolare il prodotto dei numeri interi da 1 ad n, può essere facilmente modificato per calcolare, anziché il prodotto di n numeri, la somma di n numeri; per esempio, immaginiamo di voler scrivere un programma che calcola la media di n numeri reali: prima di tutto il nostro programma dovrà leggere il valore di una variabile n di tipo int, successivamente definiremo una variabile di tipo float che chiameremo media e a cui assegneremo inizialmente il valore 0, a questo punto inizieremo un ciclo che consisterà nel ripetere per n volte le due seguenti operazioni: 1) leggi il valore di una variabile x di tipo float 2) esegui la somma media=media+x al termine del ciclo, nella variabile media sarà memorizzato il valore della somma degli n numeri reali letti; a questo punto sarà sufficiente aggiungere l’istruzione media=media/n e poi far stampare in uscita il valore di media. Ecco come si presenta un programma in C++ che calcola il valor medio di n numeri assegnati tramite la tastiera; vediamo un esempio: 12A. QUESTO PROGRAMMA CALCOLA E STAMPA IL VALOR MEDIO DI n NUMERI REALI FORNITI IN LETTURA #include <stdio.h> #include <stdlib.h> main() { int n,i;float x; printf("\n quanti sono i numeri"); printf(" di cui devo calcolare la media?"); printf("\n n= "); scanf("%d",&n); float media=0; // DICHIARAZIONE DI UNA VARIABILE IN CENTRO AL CODICE (Non necessario dichiararle all'inizio) // L'ISTRUZIONE float media=0; EQUIVALE ALLE 2 ISTRUZIONI: float media;media=0; for(i=1;i<=n;i++) { printf("\n dammi un numero reale x="); scanf("%f",&x); media=media+x; } media=media/n; printf("\n ecco il valor medio: %f\n\n",media); system ("PAUSE"); return 0; } 12B. ESEMPIO SOPRA SCRITTO CON IL WHILE AL POSTO DEL FOR #include <stdio.h> #include <stdlib.h> main() { int n,i;float x; printf("\n quanti sono i numeri"); printf(" di cui devo calcolare la media?"); printf("\n n= "); scanf("%d",&n); float media=0; //for(i=1;i<=n;i++) i=1; while (i<=n) { printf("\n dammi un numero reale x ="); scanf("%f",&x); media=media+x; i++; } media=media/n; printf("\n ecco il valor medio: %f\n\n",media); system ("PAUSE"); return 0; } 12C. ESEMPIO SOPRA SCRITTO CON IL DO-WHILE AL POSTO DEL FOR #include <stdio.h> #include <stdlib.h> main() { int n,i;float x; printf("\n quanti sono i numeri"); printf(" di cui devo calcolare la media?"); printf("\n n= "); scanf("%d",&n); float media=0; //for(i=1;i<=n;i++) i=1; do { printf("\n dammi un numero reale x ="); scanf("%f",&x); media=media+x; i++; }while (i<=n); media=media/n; printf("\n ecco il valor medio: %f\n\n",media); system ("PAUSE"); return 0; } Gli array In C++ un array ad una dimensione è semplicemente una lista di variabili che hanno tutte lo stesso nome e che vengono distinte una dall’altra mediante un indice intero; per esempio, se a è un array di tipo int, esso è un insieme (finito) di variabili di tipo int la prima delle quali viene identificata da a[0], la seconda da a[1], la terza da a[2], la n-esima da a[n-1]; quando usiamo un array in un programma C++, dobbiamo dichiararlo (esattamente come facciamo per le altre variabili), e nella dichiarazione dovrà essere specificato: 1. il tipo delle variabili che formano l’array 2. il nome comune a tutte le variabili che formano l’array 3. quante sono le variabili che formano l’array e quindi la dichiarazione: int a[10]; serve a definire un array formato da 10 variabili intere di tipo int che verranno identificate una per una da: a[0],a[1],a[2],...,a[9] e analogamente la dichiarazione float v[7]; serve a definire un array formato da 7 variabili reali di tipo float che verranno identificate una per una da: v[0],v[1],v[2],...,v[6] Come si vede quindi la prima variabile di un array ha sempre l’indice 0 e la n-esima variabile di un array avrà quindi sempre indice n-1; questo fatto è talvolta un po’ scomodo, ma come vedremo in seguito, presenta anche alcuni vantaggi non indifferenti. Tra gli oggetti matematici che più comunemente vengono rappresentati utilizzando un array, ci sono i vettori; sappiamo che, per esempio, un vettore dell’ordinario spazio euclideo (reale) ad n dimensioni può essere identificato con una n-pla di numeri reali e pertanto appare naturale rappresentare in C++ un vettore ad n dimensioni mediante un array che abbia (almeno) n elementi. Ecco per esempio un programma che calcola la media di n numeri assegnati e nel quale noi memorizziamo gli n numeri come le componenti di un vettore x: 13. QUESTO PROGRAMMA CALCOLA E STAMPA IL VALOR MEDIO DI n NUMERI REALI FORNITI IN LETTURA COME COMPONENTI DI UN VETTORE #include <stdio.h> #include <stdlib.h> main() { int n,i; float media; float x[20]; // dico il compilatore che l’array x è costituito da 20 variabili di tipo float printf("\n Quante componenti ha il vettore che devo leggere?"); printf("\n n= "); scanf("%d",&n); if (n>20) // istruzione che verifica che l'array non superi 20 { printf("\n\n Attenzione! Ci sono troppi numeri."); system(“PAUSE”); return 0; // se supero 20 interrompo l’esecuzione del programma } for(i=1;i<=n;i++) { printf("\n dammi la componente numero %d del vettore x ",i); scanf("%f",&x[i-1]); // i-1 poichè come detto gli array partono da 0 } media=0; for(i=0;i<n;i++) media=media+x[i]; media=media/n; printf("\n\n Ecco il valor medio: %f\n\n",media); system ("PAUSE"); return 0; } Facciamo alcune osservazioni sul programma dell’esempio 13 sopra: 1 la dichiarazione float x[20]; avverte il compilatore che l’array x è costituito da 20 variabili di tipo float, pertanto la dimensione n del vettore che leggeremo non potrà eccedere 20, altrimenti il nostro array non avrebbe lo spazio sufficiente per memorizzare tutte le componenti del vettore x. Ecco perché, subito dopo la lettura del valore di n abbiamo posto la istruzione if (n>20) return 0; il cui scopo è quello di interrompere l’esecuzione del programma nel caso appunto in cui sia n>20. Purtroppo il compilatore C++, nel caso in cui si cercasse di memorizzare in un array più numeri di quelli previsti dalla dimensione dell’array, non segnalerebbe alcun errore; pertanto il controllo mediante l’istruzione if (n>20) return 0; è indispensabile per evitare di trovarsi in situazioni imprevedibili. 2 nel ciclo for, l’indice i viene fatto variare da 1 ad n, ma per ogni valore di i viene letta la variabile x[i-1], ciò vuol dire che la i-esima componente del vettore che stiamo leggendo viene memorizzata nella variabile dell’array che ha nome x[i-1], e ciò dipende dal fatto che, come abbiamo detto prima, nell’array x gli indici partono dal valore 0. 3 il programma dell’esempio 13 calcola la media di n numeri dati, esattamente come il programma dell’esempio 12A, tuttavia c’è da sottolineare una importante differenza fra i due, che è la seguente: nel programma dell’esempio 12A i numeri che vengono forniti in lettura sono tutti memorizzati nella medesima variabile x, e quindi ogni volta che viene letto un nuovo numero, il precedente viene perduto, cioè alla fine della esecuzione del programma l’unico numero di cui rimanga memoria è l’ultimo numero letto; viceversa nel programma dell’esempio 13 vengono prima memorizzati nell’array x tutti gli n numeri forniti dall’utente attraverso la tastiera, e successivamente ne viene calcolata e stampata la media, pertanto alla fine del programma sono ancora accessibili tutti gli n numeri letti. (Si osservi anche che, per ragioni di chiarezza abbiamo utilizzato due cicli for, uno per la lettura dei dati e l’altro per calcolare la media, tuttavia avremmo potuto facilmente usare un unico ciclo for come nell’esempio 12A; lasciamo al lettore il compito di effettuare per esercizio la necessaria modifica). Nel programma dell’ esempio 13 l’esecuzione si interrompe nel caso in cui sia n>20; sarebbe meglio fare in modo invece che, se n>20, il programma rifiutasse il valore assegnato stampando sullo schermo un opportuno messaggio di errore, ma che poi continuasse l’esecuzione richiedendo un nuovo valore in lettura per n; ecco come possiamo ottenere tutto ciò attraverso l’uso del costrutto while: 14. QUESTO PROGRAMMA CALCOLA E STAMPA IL VALOR MEDIO DI n NUMERI REALI FORNITI IN LETTURA COME COMPONENTI DI UN VETTORE #include <stdio.h> #include <stdlib.h> main() { int n,i; float media; float x[20]; // dico il compilatore che l’array x è costituito da 20 variabili di tipo float printf("\n Quante componenti ha il vettore che devo leggere?"); printf("\n n= "); scanf("%d",&n); while (n>20) { printf("\n Attenzione!!\n le componenti del vettore sono troppe."); printf("\n Scegli di nuovo quante componenti deve avere il vettore che devo leggere"); printf("\n n= "); scanf("%d",&n); } for(i=1;i<=n;i++) { printf("\n Dammi la componente numero %d del vettore x ",i); scanf("%f",&x[i-1]); // i-1 poichè come detto gli array partono da 0 } media=0; for(i=0;i<n;i++) media=media+x[i]; media=media/n; printf("\n\n Ecco il valor medio: %f\n\n",media); system ("PAUSE"); return 0; } Scriviamo ora un programma che legge un vettore ad n componenti e ne calcola la componente massima: 15. QUESTO PROGRAMMA TROVA LA MASSIMA COMPONENTE DI UN VETTORE FORNITO IN LETTURA #include <stdio.h> #include <stdlib.h> main() { int n,i; float max; float v[31]; printf("\n\n Quante componenti ha il vettore che devo leggere?"); printf("\n n= "); scanf("%d",&n); while (n>30) { printf("\n Attenzione!!\n le componenti del vettore sono troppe."); printf("\n Scegli di nuovo quante componenti deve avere il vettore che devo leggere"); printf("\n n= "); scanf("%d",&n); } for(i=1;i<=n;i++) { printf("\n Dammi la componente numero %d del vettore x ",i); scanf("%f",&v[i]); } max=v[1]; for(i=2;i<=n;i++) if (max<v[i]) max=v[i]; printf("\n\n Massima componente=%f\n\n",max); system ("PAUSE"); return 0; } Per quanto riguarda quest’ultimo programma, osserviamo che, nel memorizzare il vettore nell’array v, abbiamo scelto di memorizzare la componente i-esima del vettore nella variabile v[i] (anziché nella variabile v[i-1] come in precedenza); ciò comporta due conseguenze: 1 la variabile v[0] non viene utilizzata mai per memorizzarvi alcuna componente del vettore 2 anche se l’array v è costituito da 31 variabili di tipo float, noi possiamo leggere vettori di dimensione al massimo 30 (appunto per il fatto che non utilizziamo la prima variabile dell’array). Tutto ciò ci porta ad evidenziare un fatto importante riguardo ai vettori ed agli array, che è il seguente: un vettore ed un array sono due cose distinte Un vettore ad n componenti, cioè una n-pla di numeri, può venire memorizzato in un array, ma non necessariamente deve occuparlo tutto, anzi di solito non lo occupa affatto tutto ma ne occupa solo una parte. Chi scrive un programma deve quindi porre particolare attenzione a questo fatto, avendo sempre presente in quale porzione dell’array si trova un certo vettore. Nel programma dell'esempio 15 abbiamo visto come trovare la massima componente di un vettore assegnato; se analizziamo l’algoritmo usato per ottenere ciò, appare subito evidente che, dopo l’esecuzione del ciclo for(i=2;i<=n;i++) if (max<v[i]) max=v[i]; nella variabile max viene a trovarsi necessariamente il valore della massima componente del vettore assegnato, tuttavia non è possibile sapere quale fosse stato il valore dell’indice i della componente massima del vettore. Se noi volessimo scrivere un programma che, oltre a determinare e stampare la massima componente di un vettore, determina e stampa anche il valore dell’indice per cui viene conseguito il massimo, dovremmo introdurre anche una variabile imax (stavolta di tipo int) in cui andare a memorizzare il valore dell’indice i ogni volta che viene cambiato il valore di max. Ecco come potremmo modificare il precedente programma per ottenere questo risultato: 16. QUESTO PROGRAMMA TROVA LA MASSIMA COMPONENTE DI UN VETTORE FORNITO IN LETTURA #include <stdio.h> #include <stdlib.h> main() { int n,i,imax; float max; float v[31]; printf("\n\n Quante componenti ha il vettore che devo leggere?"); printf("\n n= "); scanf("%d",&n); while (n>30) { printf("\n Attenzione!!\n le componenti del vettore sono troppe."); printf("\n Scegli di nuovo quante componenti deve avere il vettore che devo leggere"); printf("\n n= "); scanf("%d",&n); } for(i=1;i<=n;i++) { printf("\n Dammi la componente numero %d del vettore x ",i); scanf("%f",&v[i]); } max=v[1]; imax=1; for(i=2;i<=n;i++) if (max<v[i]) { max=v[i]; imax=i; } printf("\n\n Massima componente=%f",max); printf("\n\n Indice della massima componente=%d\n\n",imax); system ("PAUSE"); return 0; } Così come esistono gli array ad una dimensione, esistono in C++ anche gli array a due dimensioni, che sono semplicemente array con due indici anziché uno solo; le osservazioni che abbiamo fatto a proposito degli array ad una dimensione si possono estendere, con qualche ovvio aggiustamento, agli array a due dimensioni, quindi per esempio la dichiarazione float a[10][12]; serve a definire un array formato da 120(=10x12) variabili reali di tipo float che verranno identificate una per una da a[0][0],a[0][1],a[0][2],...,a[0][11], a[1][0],a[1][1],a[1][2],...,a[1][11], ..................................... a[9][0],a[9][1],a[9][2],....,a[9][11] Un uso ovvio degli array a due dimensioni in problemi matematici, è quello di utilizzarli per memorizzarvi una matrice; ecco qui di seguito un esempio di programma che fa le seguenti cose: 1 legge il numero delle righe (num_rig) e il numero delle colonne (num_col) di una matrice che dovrà essere introdotta in lettura tramite la tastiera 2 legge uno per uno gli elementi di una matrice delle dimensioni assegnate al punto 1 3 calcola e stampa la somma degli elementi di ciascuna riga 17. ESEMPIO DI ARRAY BIDIMENSIONALE #include <stdio.h> #include <stdlib.h> main() { float a[20][20]; float b[20]; int num_rig,num_col,i,j; printf("Numero delle righe della matrice: m="); scanf("%d",&num_rig); printf("Numero delle colonne della matrice: n="); scanf("%d",&num_col); printf("Introduci gli elementi della matrice\n\n"); for (i=1;i<=num_rig;i++) { for (j=1;j<=num_col;j++) { printf("a[%d,%d]=",i,j); scanf("%f",&a[i][j]); } } for (i=1;i<=num_rig;i++) { b[i]=0; for (j=1;j<=num_col;j++) b[i]=b[i]+a[i][j]; } for (i=1;i<=num_rig;i++) printf("\n b(%d)=%f\n",i,b[i]); printf("\n\n"); system ("PAUSE"); return 0; } Si osservi che nell’esempio 17 abbiamo utilizzato sia un array a due dimensioni a (per memorizzare la matrice), sia un array ad una dimensione b (per memorizzare le somme degli elementi di ciascuna riga della matrice); inoltre, sia per effettuare la lettura della matrice elemento per elemento, sia per calcolare le somme degli elementi di ciascuna riga, abbiamo dovuto utilizzare un doppio ciclo for, nel senso che abbiamo dovuto inserire due volte un ciclo for dentro un altro ciclo for. Le funzioni Cominciamo con l’esaminare il seguente programma C++: 18. QUESTO PROGRAMMA CALCOLA IL VALORE ASSOLUTO (O MODULO) DI UN NUMERO REALE ASSEGNATO #include <iostream> #include <stdlib.h> using namespace std; #include <math.h> main() { float x,y; cout<<"\n Dammi un numero reale x="; cin>>x; y=fabs(x); cout<<"\n\n modulo di "; cout<<x; cout<<" = "; system ("PAUSE"); return 0; } Rispetto ai programmi che abbiamo visto in precedenza, ci sono alcune novità che ora commenteremo: prima di tutto possiamo vedere che le istruzioni di ingresso e uscita dei dati non sono più scanf e printf; per far entrare ed uscire i dati vengono ora utilizzate cin>> e cout<<, che sembrano anche più semplici da usare rispetto a scanf e printf, infatti cin>> richiede semplicemente che gli venga accodato il nome della variabile che si vuole introdurre (da tastiera), senza bisogno di specificare con quale tipo di formato, come si faceva con scanf, e analogamente cout<< richiede che gli venga accodato il nome della variabile o la sequenza di caratteri (racchiusa fra le virgolette) che si vuole stampare sul video. Si osservi che anche per cout<< è possibile (come per printf) compattare diverse istruzioni successive di stampa; ecco come si presenterà il programma sipra compattando le istruzioni cout<<: cout<<"\n\n modulo di "<<x<<" = "<<y; Come si vede, non occorre ripetere cout<< ogni volta, ma è sufficiente accodare alla precedente variabile (o sequenza di caratteri) in uscita un nuovo simbolo << e la successiva variabile (o sequenza di caratteri) che si vuole mandare in uscita subito dopo. E' importante osservare che anche cin>> e cout<< (come scanf e printf) sono definiti in un apposito file della Libreria Standard, che è il file iostream.h (nel caso di scanf e printf era invece il file stdio.h); ecco perché in testa al programma abbiamo dovuto questa volta aggiungere la direttiva #include 1.02 - 1.03 - 1.04 - |
---|