1. Introdução
Vamos começar com uma pergunta: por que a gente precisa colocar um loop dentro do outro? É que, na real, muitas vezes nossos dados ou tarefas não são só uma linha, mas sim uma tabela, uma grade ou até uma estrutura multidimensional. Tipo, se você quiser mostrar a tabuada na tela, percorrer um array 2D ou contar as interseções entre todos os pares de elementos. Só um loop não dá conta — precisa de loop dentro de loop.
Na programação, um loop aninhado é tipo dois despertadores: o de fora começa a tocar, e dentro dele rola outro, que vai tocar toda vez enquanto o primeiro estiver ativo. Então, enquanto rola uma iteração "externa", o interno faz todo o seu rolê (e repete isso pra cada vez que o externo roda).
Um exemplo massa é horas e minutos. As horas são o loop de fora, de 0 até 23, e os minutos são o loop de dentro, de 0 até 59. Pra cada mudança no loop externo, o interno passa por todos os valores dele.
2. Sintaxe de loops aninhados
Em C#, a sintaxe dos loops aninhados é igualzinha à dos loops normais — você só escreve um loop dentro do corpo do outro. Bora ver uns exemplos com for e while:
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
Console.Write($"{i},{j} ");
}
Console.WriteLine();
}
Aqui o loop externo controla a variável i (de 0 até 2), e o interno — a variável j (de 0 até 3). Pra cada valor de i, o loop interno roda de j=0 até j=3. Se você rodar esse código, vai ver uma tabelinha de coordenadas:
0,0 0,1 0,2 0,3
1,0 1,1 1,2 1,3
2,0 2,1 2,2 2,3
Outro exemplo parecido usando while:
int i = 0;
while (i < 3)
{
int j = 0;
while (j < 4)
{
Console.Write($"{i},{j} ");
j++;
}
Console.WriteLine();
i++;
}
Saca só: dentro de cada passada do loop externo, a variável do loop interno (j) tem que ser inicializada de novo, senão você só vai ver uma linha!
3. Exemplos de uso de loops aninhados
Exemplo 1: mostrando um tabuleiro de xadrez (8x8)
Primeira missão: mostrar na tela um tabuleiro de xadrez clássico com casas pretas e brancas (vamos usar # pra preta, _ pra branca). Bora fazer com loops aninhados for:
for (int row = 0; row < 8; row++)
{
for (int col = 0; col < 8; col++)
{
if ((row + col) % 2 == 0)
Console.Write("_");
else
Console.Write("#");
}
Console.WriteLine();
}
Resultado:
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
Detalhe importante: o aninhamento garante que pra cada linha (row) a gente percorre todas as colunas (col). Sem aninhar, não ia sair o tabuleiro — só uma linha ou uma coluna.
Exemplo 2: tabuada
Esse é clássico pra loop aninhado! Bora mostrar a tabuada de 1 a 9:
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= 9; j++)
{
Console.Write($"{i * j,3} ");
}
Console.WriteLine();
}
O formatinho ${i * j,3} bota uns espaços pra tabela ficar bonitinha.
Resultado:
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
...
9 18 27 36 45 54 63 72 81
4. Loops aninhados e como controlar — as manhas
Sobre o efeito de break e continue em loops aninhados
Aqui muita gente que tá começando se enrola! Se você usar break ou continue no loop interno, eles afetam só esse loop. O externo segue de boa, como se nada tivesse rolado.
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
if (j == 3)
break; // sai só do loop interno!
Console.Write($"{i},{j} ");
}
Console.WriteLine();
}
Resultado:
0,0 0,1 0,2
1,0 1,1 1,2
2,0 2,1 2,2
Se você quiser sair de dois loops de uma vez (tipo, achou o que queria e quer parar geral), normalmente usa uma flag ou um truque (tipo return — se tudo tá dentro de uma função).
5. Visualizando loops aninhados
Às vezes é difícil "ver" a ordem de execução dos loops aninhados. Olha esse fluxograma:
Na tabela — quantas iterações rolam se i vai de 1 até 3, e j de 1 até 4?
| i | j (percorrido pra cada i) | Iterações do loop interno |
|---|---|---|
| 1 | 1, 2, 3, 4 | 4 |
| 2 | 1, 2, 3, 4 | 4 |
| 3 | 1, 2, 3, 4 | 4 |
| Total: 3 × 4 = 12 |
6. Erros e pegadinhas com loops aninhados
Erro comum — inicializar errado a variável do loop interno. Tipo, declarar ela fora do loop externo e não resetar a cada passo. Daí o loop interno pode nem rodar, ou rodar errado.
int j = 0;
for (int i = 0; i < 3; i++)
{
while (j < 4) // Opa! j já pode ser 4 depois da primeira vez.
{
Console.Write($"{i},{j} ");
j++;
}
Console.WriteLine();
}
Aqui o loop só vai rodar uma vez. Não esquece de inicializar as variáveis dos loops internos dentro dos externos!
Também, se você sem querer escrever dois loops aninhados com a mesma variável, o compilador vai reclamar: variável já definida.
for (int i = 0; i < 3; i++)
{
for (int i = 0; i < 3; i++)
{
Console.Write($"{i},{i} ");
}
Console.WriteLine();
}
GO TO FULL VERSION