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;
// Stampare un triangolo rettangolo rovesciato con asterischi
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;
int 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;
int 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
// Stampare una piramide di asterischi
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;
int main() {
int i, j, x;
const int n = 9;
x = n / 2;
// Stampare una piramide rovesciata di asterischi
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;
int main() {
int i, j, x;
const int n = 9;
x = n / 2;
// Stampare un diamante di asterischi
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++
3- Operatori di assegnazione in C++
Successione di Fibonacci in C++