In questa nona lezione del nostro corso completo di programmazione in C affronteremo un argomento piuttosto simpatico, parleremo delle istruzioni iterative.
Queste istruzioni permettono di ripetere una porzione di codice fino a quando non risulta vera una determinata condizione e, sebbene non indispensabili, sono alla base della programmazione.
Istruzione while
L’istruzione while è la più semplice tra le istruzioni iterative, il suo compito è quello di ripetere la porzione tra le parentesi graffe mentre una data condizione è vera, quando la condizione cesserà di essere vera il programma terminerà il ciclo e riprenderà la sua normale esecuzione.
La sintassi dell’istruzione while è la seguente:
while (espressione) {
...istruzioni...
...istruzioni...
}
Come nel caso del costrutto if come espressione possiamo utilizzare qualsiasi cosa che possa essere vera o falsa. Ad esempio potremmo scrivere:
while (3 < 5 ) {
printf("tre è minore di cinque!!");
}
Ma cos'ha di strano il codice che ho scritto? Che la sua esecuzione non terminerà mai! l'espressione "(3 < 5)" verrà valutata ad ogni iterazione e ad ogni iterazione risulterà invariabilmente vera, quindi il codice entrerà in un loop dal quale non riuscirà mai ad uscire. Bisogna quindi prestare attenzione che all'interno delle istruzioni del ciclo while ci siano sempre delle istruzioni in grado di rendere falsa l'espressione, solo così si potrà essere sicuri di uscire dal ciclo, come in questo esempio.
int a = 1;
while (a < 10) {
printf("a vale: %d\n", a);
a = a + 1;
}
l'output di questo programma sarà:
a vale: 1
a vale: 2
a vale: 3
a vale: 4
a vale: 5
a vale: 6
a vale: 7
a vale: 8
a vale: 9
L'output si ferma a nove, perché alla nona iterazione il valore di a, all'istruzione "a = a + 1" diventa 10, ma all'iterazione successiva l'espressione "a < 10" non è più vera quindi il programma esce dal while e riprende la sua normale esecuzione.
Notare che nel while se l'espressione è già falsa, le istruzioni contenute all'interno del blocco non vengono eseguite neanche una volta.
In un diagramma di flusso il while verrebbe così rappresentato:

Istruzione Do...while
Esiste una istruzione simile al while, ma che può risultare più utile in certi casi, si chiama do...while ed ha la seguente sintassi:
do {
...istruzioni...
...istruzioni...
} while (espressione);
Io oserei definirei speculare il suo comportamento rispetto all'istruzione while, infatti il do...while valuta l'espressione dopo aver eseguito le istruzioni contenute nel blocco e, se l'espressione risulta vera, torna all'inizio del ciclo e lo riesegue, se invece è falsa termina il ciclo.
Poiché quindi le istruzioni del blocco in questo caso vengono eseguite almeno una volta, anche se l'espressione è falsa, si usa il do...while quando si ha necessità di questo comportamento.
Ecco la rappresentazione in un diagramma di flusso del do...while:

Istruzione for
Ho lasciato per ultima l'istruzione iterativa più versatile e più complessa del linguaggio C. Qualcuno storcerà il naso dicendo "il for è una istruzione complessa??" beh, ma magari non proprio complessa, ma a volerne sfruttare tutte le capacità è abbastana tricky.
La sintassi base del for è la seguente:
for (istruzioni di inizializzazione;
condizione di ripetizione del ciclo;
istruzioni di aggiornamento) {
...istruzione...;
...istruzione...;
...
...istruzione...;
}
Prima di entrare dentro il ciclo FOR vengono eseguite le istruzioni di inizializzazione, poi inizia il ciclo e per ogni iterazione viene valutata (se presente) la condizione di ripetizione del ciclo, se tale espressione risulta vera allora vengono eseguite tutte le operazioni contenute all'interno del blocco, e al termine vengono eseguite le istruzioni di aggiornamento e ricomincia il ciclo.
Facciamo un esempio classico:
int i;
for (i = 0; i < 10; i = i + 1) {
printf("Valore di i: %d",i);
}
In questo esempio subito dopo aver dichiarato la variabile i il programma esegue l'istruzione di inizializzazione (i = 0) che ha l'effetto di impostare a zero il valore della variabile i. Poi viene valutata la condizione di ripetizione (i < 10) che risulta essere vera, quindi viene eseguita l'istruzione all'interno del blocco: printf("Valore di i: %d",i); Terminate le istruzioni all'interno del blocco viene eseguita l'istruzione di aggiornamento (i = i + 1); Quello che rende particolarmente versatile il costrutto for è che tutti e tre i parametri sono opzionali e possono essere costituiti da più di una singola istruzione. Questo può portare ad avere cicli for molto complessi come questi:
for ( ; ; ) {
...istruzioni...
}
|
Ciclo infinito, non ci sono istruzioni di aggiornemento,equivale ad un "while (true) { }" |
for (printf("Start ciclo for"), i = 0;
i < 100, printf("Valore di i %d\n",i); i = i + 1); {
...nessuna istruzione...
}
|
l'output è il seguente
ma è stato ottenuto utilizzando esclusivamente le istruzioni di inizializzazione a aggiornamento. |
for (i = 0, j = 1;
j < 10000;
printf("%d %d\n",i,j) , i = i + j , j = i + j) {
...nessuna istruzione...
}
|
Come calcolare i numeri di fibonacci minori di 10000 utilizzando apparentemente solo un ciclo for :) |
For di questo genere sono vivamente sconsigliati, rendono impossibile la lettura del codice, li ho scritti qui e non mi aspetto che vi siano subito chiari, ma li ho inseriti solo per darvi l'idea di quanto il costrutto for può essere "denaturato" fino a farci stare dentro un intero programma.
Adesso che conoscete il costrutto for eccovi una vignetta da veri geek:

Questa volta vorrei lasciarvi con un paio di esercizi, siamo già alla nona lezione ed è proprio il momento che iniziate a picchiare sulla tastiera! Io sono un teorico come indole, ma se poi vogliamo programmare davvero bisognerà iniziare a sporcarsi le mani!
Gli esercizi sono questi:
1) Far stampare a schermo un rettangolo composto da asterischi come quello qui in basso, il lato deve essere di 10 per 5 asterischi:
**********
**********
**********
**********
**********
2) Far stampare a schermo un triangolo composto da asterischi come quello qui in basso:
*
**
***
****
*****
******
*******
********
*********
3) Far stampare a schermo un triangolo composto da asterischi come quello qui in basso:
**********
*********
********
*******
******
*****
****
***
**
*
Vi do un piccolo aiuto, provate ad utilizzare due cicli for, uno dentro l'altro.
Alla prossima!!
Letture consigliate:
Il linguaggio C. Principi di programmazione e manuale di riferimento (Accademica)
Brian W. Kernighan - Dennis M. Ritchie
Editore: Pearson | Lingua: Italiano | Brossura: 313 pagine
Prezzo Listino: EUR 27,00
Prezzo Promozione: EUR 22,95 con Spedizione gratuita
C. Corso completo di programmazione
Paul J. Deitel - Harvey M. Deitel
Editore: Apogeo | Lingua: Italiano | Brossura: 640 pagine
Prezzo Listino: EUR 39,00
Prezzo Promozione: EUR 33,15 con Spedizione gratuita










57 Responses to “9. Istruzioni iterative”
20 Aprile 2011
SpartanChe mito l’immagine! 😀
20 Aprile 2011
Adrianosiete dei grandi!!
20 Aprile 2011
tommasociao a tutti!!è la prima volta che scrivo!! ringrazio moltissimo Ignazio per la bellezza del corso!! volevo inoltre chiedere una cosa; perchè se digito questo:
#include
int main(int argc, char **argv) {
int d, f ;
for (d = 1; d <= 5; d = d + 1) { printf("*\n"); for(f = 1; f <= 9; f = f + 1) { printf("*"); } } return 0; } il risultato è: * ********** ********** ********** ********** ********* e non il risultato che mi aspettavo??(esercizio 1 per casa)
20 Aprile 2011
yes77la prima l’ho risolta… ma le altre due non ci capisco una mazza 🙁
20 Aprile 2011
yes77il primo
#include
int main () {
int i;
for (i = 0; i < 5; i = i + 1)
printf("**********\n",i);
}
20 Aprile 2011
tommasoscusate se l’ho scritto 2 volte!
20 Aprile 2011
Paradisea quanto pare, stando al mio compilatore il codice
for (printf(“Start ciclo for”), i = 0;
i < 100, printf("Valore di i %d\n",i);
i = i + 1);
è sbagliato.
quello esatto dovrebbe essere:
for (printf("Start ciclo for "), i = 0;
printf("valore di i: %d\n",i), (i < 100);
i = i + 1);
PS: ancora una volta ottimo! 😉
20 Aprile 2011
Paradisesarà un po’ macchinoso, ma per ottenere il secondo esercizio ho provato così:
#include
int main(int argc, char **argv)
{
int i;
for (printf(“*\n”), i = 0; printf(“*”), (i < 1); i = i + 1); if (i=1){printf("\n");}
for (i = i; printf("*"), (i < 3); i = i + 1); if (i=3){printf("\n");}
for (i = i; printf("*"), (i < 6); i = i + 1); if (i=6){printf("\n");}
for (i = i; printf("*"), (i < 10); i = i + 1); if (i=10){printf("\n");}
for (i = i; printf("*"), (i < 15); i = i + 1); if (i=15){printf("\n");}
for (i = i; printf("*"), (i < 21); i = i + 1); if (i=21){printf("\n");}
for (i = i; printf("*"), (i < 28); i = i + 1); if (i=28){printf("\n");}
}
21 Aprile 2011
ignaziocChe compilatore stai usando? che errore ti da?
Io ho provato il codice dell’articolo e funziona correttamente, ovviamente bisogna dichiarare prima la variabile i e mettere un commento o eliminare la riga “…nessuna istruzione”
21 Aprile 2011
ignaziocdirei “troppo” macchinoso 🙂 ma almeno compila?
sconsiglio di inserire le istruzioni all’interno delle parentesi del for, io l’ho inserito come esempio, ma non è un corretto stile di programmazione. ci sono anche altre cose che non vanno, come l’utilizzo dello stesso indice che ti obbliga a verificare ogni volta se sei arrivato a fine riga…
se ti chiedessi di farlo diventare un programma che stampa un quadrato di asterischi grande 7*7 saresti costretto a modificare il tuo codice in molte parti con il rischio di sbagliare…
parliamone sul forum se vuoi.
21 Aprile 2011
ignaziocPerché il C fa quello che gli chiedi :).
Tu in questo programma hai detto
Ripeti 5 volte i prossimi comandi:
– stampa un asterisco e vai a capo
– ripeti 9 volte i prossimi comandi
–stampa un asterisco
quindi il tuo programma stampa un asterico e va a capo, poi ne stampa 9, poi ne stampa uno e va a capo, poi ne stampa nove etc etc.
ps: hai sbagliato a copiare l’output, il tuo programma stampa solo 5 righe, non 6.
21 Aprile 2011
tommasograzie mille!! in effetti è vero!!
21 Aprile 2011
alefperchè non mi compila questo??
#include
int main(int argc, char **argv)
{
int i = 1;
while (i < 6) {
printf("**********\n");
i= i + 1;
return 0;
}
non è for, ma dovrebbe andare lo stesso no?? grazie
21 Aprile 2011
alefscusate mi ero scordato la parentesi finale!!!! 🙂 funziona!
21 Aprile 2011
SpartanCi posti i risultati degli esercizi?
A me non vengono gli ultimi e non riesco a capire 🙁
22 Aprile 2011
IgnaziocLe soluzini arriveranno…sto solo aspettando un pò per farvici ragionare su.
A te ” non vengono” in che senso? direi che c’è il metodo banale che è quello di stampare:
[code]
printf(“*”);
printf(“**”);
printf(“***”);
[/code]
sarà anche banale ma in ogni caso risolve il problema.
Per farlo meglio io consiglio di usare due for tu l’hai fatto? hai risolto il primo esercizio con due for annidati?
Se lo hai fatto prova a ragionare un pò sul for più annidato…quando il ciclo più esterno è alla prima iterazioe il for più interno deve stampare un asterisco, alla seconda ne deve stampare due….
ti viene in mente niente??
22 Aprile 2011
SpartanIl primo l’ho fatto così :
#include
int main(void)
{
int i ;
for ( count = 1 ; count <= 5 ; count++ )
{
printf("**********\n");
}
return 0 ;
}
Non riesco a comprendere in che modo posso fare stampare a schermo al for più interno diversi asterischi .. a seconda del numero di iterazione.
22 Aprile 2011
SpartanPS. ho sbagliato a copiare… la variabile utilizzata è count e non i.
Comunque credo che mi fa confondere la gestione dei 2 loop for..
22 Aprile 2011
SpartanOk mi è venuto xD
#include
int main(void)
{
int a = 5 ;
int b, c ;
for(b=1; b<=a; b++) {
printf("\n");
for(c=1; c<=b; c++)
printf("*");
}
printf("\n");
}
22 Aprile 2011
RoleTheMetallerSono riuscito a farli tutti! ecco l’ultimo:
int a,b;
for (a=10; a>0; a–){
printf(“\n”);
for (b=0; b<a;b++){
printf("*");
}
}
printf("\n");
(l'ultima riga è superflua)
22 Aprile 2011
tommasomi potresti dire che cosa significano “a-” e “b++” ?
22 Aprile 2011
Spartanti rispondo io.
a- è sbagliato.. doveva essere a– .. b++ è giusto.
sono operatori di incremento e decremento.
scrivere a++ o a = a + 1 è la stessa cosa.
Identico discorso per b–
b– è come scrivere b = b – 1
Comunque c’è da fare un discorso sul post e sul pre che sicuramente ignazio tratterrà (:
22 Aprile 2011
SpartanIl sito non legge 2 meno di fila… xD
22 Aprile 2011
tommasook grazi mille!
22 Aprile 2011
FiLLo_55a– sta per a = a – 1
b++ sta per b = b + 1
22 Aprile 2011
Paradisecompila eccome! 😛 per ora di C ho seguito solo le tue lezioni, e ho cercato di integrare anche il comando IF che mi serviva per mettere gli a-capo.
bhè per il 7×7 avrei utilizzato un’altro codice, magari più semplice… 😛
22 Aprile 2011
AlessioEs. 1
#include
int main()
{
int i,j;
for (i = 0; i<5; i++ ) {
for (j = 0; j<10; j++){
printf ("*");
}
printf ("\n");
}
}
Es. 2
#include
int main()
{
int i,j;
for (i = 0; i<9; i++ ) {
for (j = 0; j<=i; j++){
printf ("*");
}
printf ("\n");
}
}
Es. 3
#include
int main()
{
int i,j;
for (i = 0; i=i; j–){
printf (“*”);
}
printf (“\n”);
}
}
Ciao e grazie!
22 Aprile 2011
AlessioL’ultimo esercizio mi si è incollato male 😐
Rieccolo:
int main()
{
int i,j;
for (i = 0; i=i; j–){
printf (“*”);
}
printf (“\n”);
}
}
22 Aprile 2011
Ignaziocok, dovrebbero andare…ma l’ultimo avrai sbagliato a copiare
22 Aprile 2011
AlessioIl sistema di commenti inibisce alcuni simboli 😐
22 Aprile 2011
AlessioVabè non me lo incolla.. cmq il terzo esercizio è identico al secondo tranne che per la J che parte da 9 e di volta in volta si ferma al valore corrente della I decrescendo di 1 ad ogni ciclo.
In questo modo parte con la prima riga e scrive 10 asterischi e via via scende di numero insieme all righe..
Ps = che fatca spiegarlo in maniera colloquiale!
Grazie ancora per il bel corso!
23 Aprile 2011
Ignaziocbeh dovrebbe andare, confronta la tua soluzione con quella che ho proposto io sul forum, vedi se la logica è la stessa.
bye
2 Maggio 2011
Teo315COMPLIMENTI per il corso! Mi ha fatto venire voglia di ricominciare a programmare (per quel poco che sapevo fare) 🙂
Ecco gli esercizi come sono venuti a me:
1)
int main()
{
int a;
for (a=1; a<6; a++){
printf("**********\n");
}
}
2)
int main()
{
int a,b;
for (a=1; a<6; a++){
for (b=1; b<=a ; b++){
printf("*");
}
printf("\n");
}
}
3)
int main()
{
int a,b;
for (a=1; a=a ; b–){
printf(“*”);
}
printf(“\n”);
}
}
Bye bye
2 Maggio 2011
Teo315mi ha tagliato un pezzo del 3) riposto:
3)
int main()
{
int a,b;
for (a=1; a=a ; b–){
printf(“*”);
}
printf(“\n”);
}
}
2 Maggio 2011
Ignaziocnei commenti il codice viene modificato, se vuoi puoi postare sul forum, cmq mi sembrano corretti.
2 Maggio 2011
Teo315Ciao Ignazio, si quando gli eseguo su code blocks mi vengono 🙂 una curiosità: quanto lunga sarà la guida? Arriveremo a fare programmi completi di UI che girano autonomamente?
Grazie
10 Giugno 2011
Luca#include
int main (int argc, const char * argv[]) {
int i,j;
for(i=1; i>9; i=i+1) {
for(j=9; j<1; j=j-i) {
printf("*");
}
printf("\n");
}
return 0;
}
Programma 2, perché non va????
10 Giugno 2011
Luca10 Giugno 2011
LucaScusate l’ho scritto in mezzo al testo, nessuno sa perché non produce alcun output?
Grazie a tutti
10 Giugno 2011
Ignaziocusi le condizioni dei for al contrario.
il secondo parametro è una condizione che se è vera entra dentro il ciclo, se è falsa esce, quindi il tuo codice non esegue praticamente nessuna istruzione
11 Giugno 2011
LucaHo provato a modificarle e mi esce un disegno strano 🙂
********
****
***
**
**
**
**
*
11 Giugno 2011
Lucacorretto l’errore! 🙂 grazie lo stesso…
22 Luglio 2011
Corso completo di Programmazione Java – I Fondamenti – Parte II | devAPP[…] for: la sintassi e il suo utilizzo sono identici a quelli del C, possiamo quindi consultare il post Istruzioni Iterative del nostro Corso Completo di C per approfondimenti. Inoltre avremo modo di approfondire i costrutti iterativi di Java in uno dei […]
21 Settembre 2011
Massimilianoaiuto ragazzi!!!!!!!!
a me non compila niente!!!!!!!!!!
nemmeno quelli che avete postato voi che a voi funzionano!!!!
io uso Xcode e come progetto faccio Command line tool…
🙁 vi prego aiuto… ci divento pazzo……..
22 Settembre 2011
Ignaziocche errori ti da?
27 Settembre 2011
NicolaIo li ho risolti così…senza for…
QUADRATO
#include
int main (int argc, const char * argv[]) {
int i = 0;
int g = 0;
while (g <= 4) {
printf("*");
i = i + 1;
if (i == 11) {
printf("\n");
i = 0;
g = g + 1;
}
}
}
TRIANGOLO 1
#include
int main (int argc, const char * argv[]) {
int i = 0;
int g = 1;
while (g <= 10) {
printf("*");
i = i + 1;
if (i == g) {
printf("\n");
i = 0;
g = g + 1;
}
}
}
PIRAMIDE 2
#include
int main (int argc, const char * argv[]) {
int i = 0;
int g = 10;
while (i <= g) {
printf("*");
i = i + 1;
if (i == g) {
printf("\n");
i = 0;
g = g – 1;
}
}
}
…funzionano
28 Settembre 2011
Millemanciao, io ho pensato di farlo così
*******************************************************
#include
int main()
{
// primo esercizio
int i;
printf(“primo esercizio \n\n”);
for (i = 0; i < 5; i = i + 1)
{
printf("**********\n");
}
printf("\n\nsecondo esercizio \n\n");
// secondo esercizio
int j;
for (i = 1; i<11; i++)
{
for (j = 1; j <= i; j++ )
{
printf("*");
}
printf("\n");
}
printf("\n\nterzo esercizio \n\n");
// terzo esercizio
for (i = 1; i= i; j– )
{
printf(“*”);
}
printf(“\n”);
}
return 0;
}
28 Settembre 2011
Millemanma viene tutto modificato da come l’ho scritto…perchè??
#include
int main()
{
// primo esercizio
int i;
printf(“primo esercizio \n\n”);
for (i = 0; i < 5; i = i + 1)
{
printf("**********\n");
}
printf("\n\nsecondo esercizio \n\n");
// secondo esercizio
int j;
for (i = 1; i<11; i++)
{
for (j = 1; j <= i; j++ )
{
printf("*");
}
printf("\n");
}
printf("\n\nterzo esercizio \n\n");
// terzo esercizio
for (i = 1; i= i; j– )
{
printf(“*”);
}
printf(“\n”);
}
return 0;
}
28 Settembre 2011
IgnaziocI codici scritti nei commenti non vanno bene perché si perde l’indentazione e alcuni caratteri speciali vengono modificati.
Se avete voglia di condividere le vostre soluzioni utilizzate il forum.
7 Novembre 2011
Severinoint main ()
{
int l;
for (int a = 10;a > 0; a–)
{
for(l=1;l<=a; l++)
{
printf("*");
}
printf("\n");
}
return 0;
}