In questa lezione affronteremo i cicli for annidati in C++, cioè le iterazioni eseguite dentro un’altra iterazione.

Facciamo subito degli esempi per capire meglio il funzionamento.

Esempio sui cicli for annidati C++

Produrre un programma che mostri un rettangolo di 6 asterischi come base e 3 come altezza.

Quindi per risolvere questo problema abbiamo bisogno di due cicli, uno più esterno ed uno più interno.

Quando quello più esterno viene eseguito la prima volta, in quello più interno stamperemo i 6 asterischi, faremo cioè la prima riga.

Dopo andiamo a capo con un endl ed eseguiamo il ciclo esterno la seconda volta. Il ciclo interno è eseguito nuovamente 6 volte.

E così anche per la terza riga.

Abbiamo bisogno di due contatori, uno per il for esterno, l’altro per quello interno. Chiamiamo questi contatori per convenzione i e j.

Ecco dunque il codice di esempio per i cicli for annidati in C++:

#include <iostream>
using namespace std;

int main() {
	int i,j;
	
	for(i=0;i<3;i++) { 
		for (j=0;j<6;j++) {
			cout<<" * ";
		}
		cout<<endl;
	}			
	return 0;
}

Ecco l’algoritmo spiegato passo passo:

Prima iterazione ciclo esterno:

i=0  Nel ciclo interno j verrà incrementato di 1, sei volte (j=0, j=1, j=2, j=3, j=4, j=5), quindi stamperà * * * * *

Seconda iterazione ciclo esterno:

i=1 Sempre nel ciclo interno j verrà incrementato di 1, sei volte (j=0, j=1, j=2, j=3, j=4, j=5), quindi stamperà * * * * *

Terza iterazione ciclo esterno:

i=2 Allo stesso modo nel ciclo interno j verrà incrementato di 1, sei volte (j=0, j=1, j=2, j=3, j=4, j=5), quindi stamperà * * * * *

Il ciclo termina perché i diventa 3 e la condizione i<3 non è più verificata.

Il risultato sarà dunque questo, un rettangolo di asterischi:

* * * * *
* * * * *
* * * * *


Secondo esempio for annidati

Modifichiamo l’algoritmo precedente stampando adesso un triangolo.

Produrre un programma che mostri un triangolo rettangolo di asterischi avente come altezza 4, come da figura sotto:

*
**
***
****

Quindi intuiamo che il ciclo più esterno deve essere eseguito 4 volte e quello più interno la prima volta 1, la seconda 2, la terza 3, la quarta 4.

#include <iostream>
using namespace std;

int main() {
	int i,j;

        const int h=4;
	
	for(i=0;i<h;i++) { 
		for (j=0;j<1+i;j++) {
			cout<<" * ";
		}
		cout<<endl;
		
	}			
	return 0;
}

Nella prima iterazione del ciclo esterno:

i=0 Nel ciclo interno j verrà incrementato di 1, una volta (j=0), poiché nell’iterazione successiva j diventerebbe 1 e la condizione 1<1+i non è più verificata. Quindi stamperà *

La seconda iterazione del ciclo esterno porterà:

i=1 e nel ciclo interno j verrà incrementato due volte di 1 (j=0, j=1), quindi stamperà * *

Nella terza iterazione del ciclo esterno:

i=2 e j verrà incrementato tre volte di 1 (j=0, j=1, j=2), quindi stamperà * * *

Nella quarta iterazione del ciclo esterno:

i=3 e j verrà incrementato di 1, tre volte (j=0, j=1, j=2,j=3), quindi stamperà * * * *

Il ciclo termina perché i diventa 4 e la condizione i<4 non è più verificata.

Dunque il risultato sarà dunque, un triangolo rettangolo di asterischi:

*
* *
* * *
* * * *

Terzo esempio

Produrre un programma che mostri un triangolo rettangolo di asterischi avente come altezza 4, come da figura sotto:

****
***
**
*

Quindi intuiamo che il ciclo più esterno deve essere sempre eseguito 4 volte mentre quello più interno questa volta dobbiamo iniziare da h-i, ovvero da destra e decrementare j di volta in volta.

#include <iostream>
using namespace std;

int main() {
	int i,j;

        const int h=4;
	
	for(i=0;i<h;i++) { 
		for (j=h-i;j>0;j--) {
			cout<<"*";
		}
		cout<<endl;
		
	}			
	return 0;
}

Quarto esempio

Produrre un programma che mostri una figura come quella sotto:

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

main(){
	int i,j,n;
        n=8;
	
	for(i=0;i<n;i++) {
		for(j=1;j<=n;j++){
			if(j<n-i && j>i || j<=i && j>=n-i)
				cout<<"*";
			else
				cout<<" ";
		  }
		
		cout<<endl;
	}
        return 0;
}

Quinto esempio

Produrre un programma che mostri una figura come quella sotto:

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

main(){
	int i,j,n;
        n=8;
	
	for(i=0;i<n;i++) {
		for(j=0;j<=n;j++){
			if(j<=n-i && j>=i || j<=i && j>=n-i)
				cout<<" ";
			else
				cout<<"*";
		  }
		
		cout<<endl;
	}
        return 0;
}

Sesto esempio

Variamo ancora la figura da creare, creando un triangolo isoscele.

Produrre un programma che mostri un triangolo isoscele di asterischi avente come base 9, come da figura sotto:

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

int main() {
	int i,j,x;
	
	const int n=9;
	
	x=n/2+1; //troviamo l'altezza
	
	for(i=0;i<x;i++) { 
		for (j=0;j<x+i;j++) {
			if (x-j-1>i)
				cout<<" ";
			else
				cout<<"*";
		}
		cout<<endl;	
	}			
	return 0;
}

Poniamo x uguale alla metà della base più 1, ottenendo in questo caso 5 che rappresenta la nostra altezza.

Poi inseriamo i due cicli for. Il ciclo esterno va da 0 ad x-1, il ciclo interno da 0 a x+i-1. Il ciclo interno verrà eseguito una volta in più ad ogni iterazione del ciclo esterno. Quindi esaminiamo nel dettaglio le iterazioni.

Prima iterazione ciclo esterno:

i=0 Nel ciclo interno j è incrementato di 1, cinque volte (j=0, j=1, j=2, j=3, j=4). Ogni volta si controlla se questa condizione è vera x-j-1>i e dunque si stampa il carattere vuoto, altrimenti si stampa l’asterisco.

5-0-1>0 cioè 4>0 vera spazio bianco

5-1-1>0 cioè 3>0 vera spazio bianco

5-2-1>0 cioè 2>0 vera spazio bianco

5-3-1>0 cioè 1>0 vera spazio bianco

5-4-1>0 cioè 0>0 falsa asterisco

Quindi stamperà 4 spazi bianchi e un     *

Seconda iterazione ciclo esterno:

i=1 Sempre nel ciclo interno j riparte da 0 ed è incrementato di 1, sei volte. Analizziamo anche questa volta la condizione x-j-1>i

5-0-1>1 cioè 4>1 spazio bianco

5-1-1>1 cioè 3>1 spazio bianco

5-2-1>1 cioè 2>1 spazio bianco

5-3-1>1 cioè 1>1 asterisco

5-4-1>1 cioè 0>1 asterisco

5-5-1>1 cioè -1>1 asterisco

Quindi stamperà tre spazi bianchi e tre   * * *

E così via! In output visualizzeremo un triangolo isoscele. 

Analogamente potevamo anche ragionare in questo modo:

#include <iostream>
using namespace std;

main(){
	int i,j,x;
        const int n=9;
        x=n/2;

	for(i=0;i<=x;i++) {
		for(j=0;j<=x+i;j++){
			if(j>x-i-1)
				cout<<"*";
			else
				cout<<" ";
		  }
		cout<<endl;
	}
    return 0;
}

Settimo esempio

Costruiamo un rombo come da figura sotto:

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

main(){
	int i,j,x;
        const int n=9;
        x=n/2;

	for(i=0;i<=n;i++) {
		for(j=0;j<=x+i;j++){
			if(j>x-i-1 && i<=x)
				cout<<"*";
			else if (i>=x && j>=i-n/2 && j<n-i+n/2) 
			    cout<<"*";		
			else
				cout<<" ";
		  }
		cout<<endl;
	}
    return 0;
}

Nella prossima lezione svilupperemo altri esempi sui cicli for annidati in C++.

Alcuni link utili

Indice argomenti linguaggio C++

1- Introduzione al linguaggio C++

2- Variabili in C++

3- Operatori di assegnazione in C++

4- Esempi in C++

5- Casting in C++

Successione di Fibonacci in C++