Affrontiamo oggi un esercizio sui cicli con i flow chart per consolidare l’argomento sulle iterazioni. Utilizzeremo ancora il while ma presto vi parlerò di altre istruzioni iterative.
Prendere in input 10 numeri e sommare solo i positivi.
Per risolvere questo semplice algoritmo, dobbiamo innanzitutto prendere il numero e valutare se è maggiore di zero. Se è vero lo aggiungiamo alla variabile somma, altrimenti non facciamo nulla.
In ogni caso il contatore verrà incrementato o decrementato, a seconda di come imposto il problema.
Esercizio sui cicli con i flow chart – primo procedimento
Innanzitutto inizializziamo a 0 conta e somma. Ricordiamo che nell’ultima versione di Algobuild occorre utilizzare l’assegnazione somma=0.0. Oppure dichiarare n intero (int n), in effetti questa soluzione, se dobbiamo trattare solo interi è la più indicata.
Dopo inseriamo il ciclo while e impostiamo la condizione conta<10. Poi chiediamo di inserire il numero n e per ogni numero chiediamo se è positivo. Se la condizione è vera allora aggiungiamo il numero alla variabile della somma, altrimenti non si fa nulla.
Infine visualizziamo in output, fuori dal ciclo, la somma così ottenuta.
Esercizio sui cicli con i flow chart – secondo procedimento
In questa seconda soluzione impostiamo N a 10. Dopo inizializziamo la somma a zero e finché N è positivo continuiamo a fare queste operazioni:
Inseriamo in input il numero n;
Dopo, con l’if (la selezione) facciamo un test per vedere se il numero è positivo: n>0. Se la condizione è vera sommiamo n alla variabile somma, altrimenti non facciamo nulla.
Poi decrementiamo N di uno.
Alla fine del ciclo stampiamo la somma dei numeri positivi.
Ecco quindi l’esercizio sui cicli rappresentato con i flow chart:
Chiaramente questo è solo un semplice esercizio sui cicli utilizzando i flow chart.
Iterazione vuol dire ripetere una o più istruzioni un certo numero di volte, per ottenere il risultato desiderato.
Iterazione con i diagrammi di flusso – esempi
Di seguito ecco l’algoritmo da risolvere:
Prendere in input 10 numeri e contare quanti numeri pari e quanti dispari sono stati inseriti.
Proponiamo di risolvere questo algoritmo iterativo utilizzando il ciclo while, anche se precisiamo è un ciclo con contatore e quindi il ciclo for sarebbe più indicato. Difatti questa risoluzione viene affrontata esclusivamente per permettere una discussione ed un confronto tra i due metodi.
Iterazione – Primo metodo
Innanzitutto inizializziamo a zero le variabili che ci servono.
In questo caso sono conta, contap e contad e per comodità le ho inserite in un unico rettangolo. Dopo inseriamo il ciclo while impostando la condizione conta<10.
Quindi chiediamo di inserire in input il numero n e controlliamo se è pari.
Per controllare se un numero è pari si considera il resto della divisione del numero diviso 2. Se è pari, incrementiamo il contatore dei pari, altrimenti incrementiamo il contatore dei dispari.
Non dimentichiamo di incrementare conta, altrimenti il ciclo sarà infinito.
Al termine dire quanti sono i numeri pari e dispari inseriti.
Iterazione con i diagrammi di flusso – secondo metodo
Per risolvere l’algoritmo innanzitutto assegniamo ad N il valore 10, in quanto dobbiamo inserire 10 elementi.
N=10
Successivamente per ogni elemento inserito decrementeremo N.
Dopo inizializziamo anche le due variabili contap e contad a zero:
contap=0 e contad=0
Queste variabili dunque serviranno per contare quanti numeri pari e dispari sono stati inseriti.
Successivamente realizziamo un ciclo while dove metteremo la condizione: N>0. Il ciclo cioè continuerà finché N sarà positivo.
Le istruzioni che saranno eseguite all’interno del ciclo while sono:
Chiediamo in input il numero n;
Dopo, utilizzando l’istruzione di selezione if, facciamo un test per vedere se il numero è pari: n%2==0. Cioè il resto della divisione di n diviso due è uguale a zero? Ricordiamo che % è l’operatore modulo che permette di calcolare il resto della divisione. Quindi se la condizione è vera incrementiamo il contatore dei pari (contap=contap+1), altrimenti incrementiamo quello dei dispari (contad=contad+1).
Poi decrementiamo N di uno.
Alla fine del ciclo stampiamo i valori dei due contatori ottenuti.
Ecco quindi l’algoritmo di iterazione sviluppato con il diagramma di flusso:
Chiaramente ci possono essere tante altre soluzioni all’algoritmo proposto.
Questo è solo un semplice esempio di iterazione rappresentato con i diagrammi di flusso.
In questa lezione sui cicli e diagrammi di flusso, affronteremo un altro esercizio con il ciclo while.
Cicli e diagrammi di flusso – esercizio
Prendere in input 10 numeri ed effettuare il loro prodotto. Al termine visualizzare il risultato ottenuto.
Per lo sviluppo del seguente algoritmo mi servirà una variabile conta che si incrementa di 1 ogni volta che inseriremo il numero, come abbiamo già visto negli esempi precedenti.
Dopo ci servirà una variabile prodotto dove andare a memorizzare il risultato della nostra operazione.
Ma a quanto deve essere inizializzato il prodotto? Chiaramente non può essere inizializzato a 0, in quanto altrimenti il prodotto sarebbe sempre nullo.
Dunque occorre inizializzare il prodotto a 1, che è l’elemento neutro.
Al termine dell’algoritmo stampiamo il prodotto nel ramo del falso del ciclo while. Ho utilizzato un unico parallelogramma dove ho inserito sia la frase, tra virgolette, sia la variabile prodotto, senza virgolette.
Ecco di seguito l’algoritmo sui cicli e diagrammi di flusso che effettua il prodotto di 10 numeri.
Per lo sviluppo dell’algoritmo abbiamo utilizzato dunque queste forme:
Ellisseper l’inizio e per la fine.
Parallelogramma per inserire l’input, ovvero in questo caso i nostri numeri da moltiplicare e per visualizzare l’output.
Rettangolo per assegnare un valore alle variabili e per effettuare il calcolo del prodotto.
Romboper il ciclo while.
Quindi ecco il diagramma di flusso che rappresenta l’algoritmo per il calcolo del prodotto di 10 numeri utilizzando i cicli.
Questo è solo un semplice esempio sui cicli e diagrammi di flusso, più avanti faremo altri esempi.
Il ciclo while, che abbiamo introdotto nella scorsa lezione, serve a ripetere delle istruzioni un determinato numero di volte. Il ciclo while è dunque indicato ad esempio quando dobbiamo prendere N numeri e li dobbiamo sommare, ed in tantissimi altri casi.
Continuiamo a fare degli esempi di utilizzo.
Uso del ciclo while – esempio
Prendere in input 10 numeri e sommarli, quindi visualizzare la somma in output.
Analizziamo il problema. Ci serve, come spiegato nella precedente lezione, un contatore che parte da 0 e che si fermi a 9.
Ogni volta che prendiamo in input un numero poi dobbiamo memorizzarlo in una variabile somma che inizializziamo a 0. Nella nuova versione di Algobuild occorre inizializzarla a 0.0 per non avere errori.
Infatti, se non dichiariamo il tipo di dato del numero n, preso in input, di default Algobuild considera questo numero come double.
Quindi, ogni volta, dobbiamo sommare il nuovo numero alla variabile iniziale che ha valore 0. Ricordiamo infatti che 0 è l’elemento neutro della somma, in quanto il risultato finale non viene alterato.
Ecco dunque l’algoritmo completo che realizza la somma di 10 numeri con il ciclo while.
Ricordiamo che nel while, verrà intrapreso il percorso verso il basso se la condizione espressa all’interno del while (rombo) è vera. Mentre si prenderà il percorso a destra quando la condizione all’interno del while è falsa.
Seconda soluzione
Possiamo anche realizzare il ciclo partendo da 10, decrementandolo ogni volta di 1. In pratica utilizziamo direttamente N come contatore.
Quindi assegniamo ad N il valore 10 e lo decrementeremo di 1 per ogni numero che inseriremo.
Poi inizializziamo la variabile somma a zero, cioè scriviamo somma=0.
Se lo sviluppiamo con Algobuild, nella nuova versione, occorre indicare il valore 0.0.
Impostiamo poi la condizione all’interno del while: N>0, cioè finché N è positivo eseguiamo queste istruzioni:
Inseriamo in input il numero n;
Sommiamo il numero n: somma=somma+n. Quindi la prima volta che sarà eseguita questa istruzione avremo: somma=0+n, infatti 0 è l’elemento neutro della somma. Non fare l’inizializzazione comporterebbe degli errori, in quanto le variabili non inizializzate contengono dei cosiddetti valori “immondizia” cioè contengono l’ultimo dato immagazzinato nella locazione di memoria riservata per quella variabile.
Decrementiamo N di uno.
Tutto ciò verrà ripetuto 10 volte, ecco i decrementi che subirà N: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0. Quando arriva a zero uscirà dal ciclo while, perché la condizione (N>0) è falsa, dunque stamperemo la somma totale.
Ecco dunque il diagramma a blocchi completo dell’algoritmo per la somma di 10 numeri, realizzato con l’uso del ciclo while. Per lo sviluppo ho utilizzato il software Algobuild nella versione vecchia, nella nuova vi ricordo di impostare somma=0.0.
Questo è solo un semplice esempio di utilizzo del ciclo while con i diagrammi di flusso, ne proporrò tanti altri.
In questo articolo parleremo degli array e puntatori in C, ovvero di due elementi strettamente correlati tra loro. Infatti il compilatore gestisce sempre gli array con la logica dei puntatori.
Abbiamo studiato come accedere agli elementi di un array per mezzo di un indice, adesso vedremo come accedere per mezzo di un puntatore.
Dunque, se consideriamo ad esempio un array a e una variabile puntatore pa:
int a[10];
int *pa;
Potremmo utilizzare indifferentemente le due assegnazioni equivalenti:
pa=&a[0];oppure
p=a;
Quindi, come potete notare, il nome dell’array è usato come un puntatore al suo primo elemento.
In C il nome dell’array, come nel nostro caso a, è una costante, non una variabile.
Esempio di utilizzo di Array e puntatori
Quindi, come dicevamo, il nome di un array è un puntatore costante al primo elemento di un array. Dunque facciamo questo semplice esempio, dove entrambi i printf stampano l’indirizzo del primo elemento di a.
#include <stdio.h>
int main() {
int a[5];
int *p;
p=a; //avrei potuto scrivere anche p=&a[0]
printf("indirizzo: %p ", a);
printf("indirizzo: %p ", p);
return 0;
}
Consideriamo adesso che l’espressione a[i] non fa altro che aggiungere al puntatore implicito a il valore della variabile intera i e applicare al risultato ottenuto l’operatore di in-direzione *. Dunque scrivere a[i] è equivalente a scrivere *(a+i).
Facciamo quindi un semplice esempio:
#include <stdio.h>
int main() {
int a[5]={6,3,4,8,9};
printf("\nValore: %d", a[2]);
printf("\nValore: %d", *(a+2));
return 0;
}
Entrambi i printf stamperanno il valore 4.
Anche se è meno comune, potrei scrivere anche in questo modo:
#include <stdio.h>
int main() {
int a[5]={6,3,4,8,9};
printf("\nValore: %d", 2[a]);
printf("\nValore: %d", *(2+a));
return 0;
}
Quindi c’è equivalenza tra puntatori e nomi di vettori, ma è importante dire che i puntatori rappresentano delle variabili, mentre i nomi dei vettori rappresentano delle costanti.
A un puntatore infatti viene allocata la memoria necessaria a contenere l’indirizzo dell’oggetto puntato mentre a un array viene assegnato lo spazio necessario per contenere gli elementi.
Precisiamo dunque che se p è un puntatore e a è un array, le operazioni: p++; e pure p=a; sono così consentite. Mentre non sono consentite a++; e anche a=p.
Altri esempi con array e puntatori
Facciamo altri semplici esempi per rafforzare quanto detto.
Prendiamo dunque un array a e sommiamo tutti gli elementi, noterete che entrambi i metodi proposti sono equivalenti.
#include <stdio.h>
int main() {
int a[5]= {9,5,6,7,10};
int i,sum=0;
for(i=0; i<5; i++)
sum += a[i];
printf("\nStampa la somma %d", sum);
sum=0;
for(i=0; i<5; i++)
sum += *(a+i);
printf("\nStampa la somma %d", sum);
return 0;
}
Anche con quest’altro esempio otterremo lo stesso risultato, fate attenzione all’ultimo ciclo for, che non fa uso dell’indice i ma del puntatore. Avrei potuto scrivere il secondo for anche così: for(; p<(a+5); p++).
#include <stdio.h>
int main() {
int a[5]= {9,5,6,7,10};
int *p = &a[0];
int i,sum=0;
for(i=0; i<5; i++)
sum += p[i];
printf("\nStampa la somma %d", sum);
sum=0;
for(p=a; p<(a+5); p++)
sum += *p;
printf("\nStampa la somma %d", sum);
return 0;
}
In questa lezione abbiamo parlato di array e puntatori, torneremo ancora a parlare di questo argomento nelle prossime lezioni, al fine di approfondire questi concetti.