I cicli annidati consentono di eseguire una sequenza di cicli all'interno di un altro. Vengono utilizzati quando è necessario iterare su strutture multidimensionali, come array bidimensionali o combinazioni di elementi. Il primo ciclo è chiamato esterno, mentre quello che si trova all'interno è interno.
La necessità di lavorare con strutture annidate, come matrici o grafi, ha portato all'emergere dei cicli annidati. I linguaggi di programmazione, inclusi Java, supportano intrinsecamente questo meccanismo per affrontare compiti di elaborazione di array, grafi, reticoli, ecc.
L'uso di cicli annidati può portare a una elevata complessità temporale se non si tiene conto del numero di iterazioni. Spesso si riscontrano problemi con la leggibilità del codice e errori di indicizzazione. Un uso scorretto porta a eseguire ripetutamente le stesse azioni.
Esempio di codice:
int[][] matrix = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[i].length; j++) { System.out.print(matrix[i][j] + " "); } System.out.println(); }
Caratteristiche chiave:
È possibile terminare entrambi i cicli con un singolo break?
Il normale operatore break termina solo il ciclo interno. Per uscire da più cicli, vengono utilizzate etichette (label):
outer: for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (condizione) break outer; } }
È possibile avere un ciclo infinito a causa di cicli annidati?
Sì, se la condizione di uscita da uno qualsiasi dei cicli è implementata in modo errato, si genererà un ciclo infinito. Questo accade frequentemente a causa di errori nell'inizializzazione o nell'incremento del contatore.
È possibile modificare le variabili del ciclo esterno dal ciclo interno?
Sì, tecnicamente è possibile, ma questo compromette gravemente la leggibilità del codice e porta a errori. È meglio evitarlo e separare chiaramente il lavoro di ciascun ciclo.
Viene implementata l'iterazione su un array bidimensionale, ma invece di i e j si usa sempre i:
for (int i = 0; i < n; i++) { for (int i = 0; i < m; i++) {...} }
Pro:
Contro:
Si utilizzano nomi di variabili diversi:
for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) {...} }
Pro:
Contro: