Estruturas de repetição aninhadas
Combine laços para percorrer duas dimensões, prever a ordem das iterações e calcular o trabalho realizado pelo bloco interno.

O laço interno completa um percurso para cada volta externa
Uma estrutura de repetição aninhada coloca um laço dentro do corpo de outro. O laço externo seleciona um contexto; dentro dele, o laço interno percorre todos os elementos daquele contexto.
Imagine um pequeno cinema com três fileiras e quatro assentos em cada uma:
A1 A2 A3 A4
B1 B2 B3 B4
C1 C2 C3 C4
O laço externo pode controlar a fileira, enquanto o interno controla o assento:
PARA CADA fileira EM ["A", "B", "C"] FAÇA
PARA assento DE 1 ATÉ 4 FAÇA
EXIBIR fileira, assento
FIM PARA
FIM PARA
A fileira A permanece selecionada enquanto o laço interno percorre 1, 2, 3 e 4. Somente depois de o laço interno terminar, o externo avança para B e inicia um novo percurso dos assentos.
Aninhar não cria um novo tipo de laço. É uma composição das estruturas que você já conhece, como o for, com responsabilidades diferentes para cada nível.
Acompanhe os pares na ordem em que são produzidos
Em JavaScript, o exemplo fica assim:
const fileiras = ["A", "B", "C"];
for (const fileira of fileiras) {
for (let assento = 1; assento <= 4; assento += 1) {
console.log(`${fileira}${assento}`);
}
}
A saída é:
A1 A2 A3 A4 B1 B2 B3 B4 C1 C2 C3 C4
O rastreamento por volta externa torna o reinício visível:
| Fileira externa | Valores assumidos por assento | Pares produzidos |
|---|---|---|
A | 1, 2, 3, 4 | A1, A2, A3, A4 |
B | 1, 2, 3, 4 | B1, B2, B3, B4 |
C | 1, 2, 3, 4 | C1, C2, C3, C4 |
As variáveis têm ciclos de vida distintos. fileira muda três vezes; assento percorre quatro valores em cada uma dessas vezes. Usar nomes que expressem cada dimensão reduz a chance de atualizar ou consultar o nível errado.
Inverter os laços muda a ordem, não necessariamente a cobertura
Troque as posições:
const fileiras = ["A", "B", "C"];
for (let assento = 1; assento <= 4; assento += 1) {
for (const fileira of fileiras) {
console.log(`${fileira}${assento}`);
}
}
Agora a saída é:
A1 B1 C1 A2 B2 C2 A3 B3 C3 A4 B4 C4
Os mesmos doze pares aparecem, mas agrupados por número de assento em vez de fileira. Portanto, duas perguntas devem ser avaliadas separadamente:
- cobertura: quais combinações serão visitadas;
- ordem: qual combinação aparece antes de qual.
Em alguns problemas, somente a cobertura importa. Em outros, a ordem afeta a apresentação, o estado acumulado, o acesso aos dados ou a possibilidade de interromper cedo. Escolha o nível externo conforme o contexto que precisa permanecer fixo durante um percurso interno completo.
Calcule o trabalho contando as voltas internas
No cinema:
- o laço externo executa 3 vezes;
- para cada uma, o interno executa 4 vezes;
- o
console.logexecuta3 × 4 = 12vezes.
Essa multiplicação funciona porque os quatro assentos são percorridos para cada uma das três fileiras. Para limites independentes com f fileiras e a assentos, o bloco mais interno executa:
f × a
Não conte apenas quantas instruções for aparecem. Conte quantas vezes o corpo interno executa em cada valor externo.
Isso também impede uma conclusão precipitada: dois laços aninhados não significam automaticamente “o primeiro limite ao quadrado”. Se existem 3 fileiras e 100 assentos, são 300 pares, não 100² nem 3².
Esta aula usa contagem exata para compreender o fluxo. A comparação formal de crescimento e custo pertence à aula posterior de eficiência.
Limites dependentes formam outros desenhos
O número de voltas internas pode depender do valor externo. Para desenhar uma escada com quatro níveis:
for (let linha = 1; linha <= 4; linha += 1) {
let desenho = "";
for (let coluna = 1; coluna <= linha; coluna += 1) {
desenho += "■";
}
console.log(desenho);
}
Resultado:
■
■■
■■■
■■■■
O laço interno não executa quatro vezes em toda linha:
linha | Voltas internas |
|---|---|
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| Total | 1 + 2 + 3 + 4 = 10 |
Para prever o total, faça uma linha da tabela para cada valor externo e some as voltas internas. Só transforme essa soma em multiplicação quando a quantidade interna realmente for constante.
Cada nível precisa terminar por conta própria
As condições de parada continuam válidas em cada nível:
- o laço interno precisa avançar até sua própria saída;
- depois que ele termina, o laço externo precisa avançar;
- reiniciar o laço interno não pode apagar indevidamente o estado externo;
- nenhum caminho com
continuepode pular a atualização necessária do nível que ele repete.
Se o laço interno fica infinito na fileira A, o externo nunca alcança B. O problema parece envolver a grade inteira, mas a primeira pergunta de diagnóstico é: qual nível deixou de progredir?
Em laços controlados manualmente, use variáveis diferentes:
fileira <- 0
ENQUANTO fileira < 3 FAÇA
assento <- 0
ENQUANTO assento < 4 FAÇA
EXIBIR fileira, assento
assento <- assento + 1
FIM ENQUANTO
fileira <- fileira + 1
FIM ENQUANTO
assento é reiniciado dentro do corpo externo porque cada fileira precisa começar no primeiro assento. fileira é inicializada antes dos dois laços, pois seu estado deve sobreviver a todos os percursos internos.
break normalmente encerra apenas o laço mais interno
Considere uma busca pelo assento B3:
for (const fileira of ["A", "B", "C"]) {
for (let assento = 1; assento <= 4; assento += 1) {
if (`${fileira}${assento}` === "B3") {
break;
}
console.log(`${fileira}${assento}`);
}
}
Ao encontrar B3, break encerra o laço dos assentos. O laço das fileiras continua e começa C1. Em JavaScript e em várias linguagens de sintaxe semelhante, uma interrupção sem rótulo afeta o laço mais próximo.
Quando a intenção é encerrar toda uma busca, uma função pode tornar a saída explícita:
function localizarAssento(alvo) {
for (const fileira of ["A", "B", "C"]) {
for (let assento = 1; assento <= 4; assento += 1) {
const codigo = `${fileira}${assento}`;
if (codigo === alvo) {
return { fileira, assento };
}
}
}
return null;
}
console.log(localizarAssento("B3"));
Resultado:
{ fileira: "B", assento: 3 }
JavaScript também oferece break com rótulo. Antes de usá-lo, avalie se extrair a busca para uma função deixa intenção, resultado e testes mais claros. O importante é escolher conscientemente qual nível deve terminar.
Evite níveis que não representam dimensões reais
Aninhamento é apropriado quando o problema contém relações como:
- cada fileira com seus assentos;
- cada produto combinado com cada região;
- cada dia dividido em horários;
- cada ponto inicial comparado com candidatos.
Ele merece revisão quando:
- três ou mais níveis exigem lembrar muitas variáveis ao mesmo tempo;
- o corpo interno mistura validação, cálculo, formatação e saída;
- a mesma busca interna é refeita sem necessidade;
- nomes genéricos como
i,jekescondem o significado; break,continuee sinalizadores tornam o destino do fluxo difícil de prever.
Não remova um laço necessário apenas para reduzir indentação. Primeiro identifique o que cada nível representa; depois considere separar responsabilidades em operações nomeadas. Essa preparação abre o próximo módulo da trilha.
Teste ordem, limites e interrupções
Use um teste de mesa que registre uma linha por execução do corpo mais interno:
| Passo | Valor externo | Valor interno | Ação | Houve interrupção? |
|---|
Inclua casos com:
- conjunto externo vazio;
- conjunto interno vazio;
- uma única combinação;
- dimensões diferentes, como 2 × 5;
- limite interno dependente do externo;
- alvo encontrado na primeira e na última combinação;
- alvo ausente;
breakecontinueem cada nível relevante.
Confirme três resultados: pares produzidos, ordem desses pares e quantidade de execuções do corpo interno.
Pratique com rotas e horários
Uma transportadora atende três rotas, Norte, Centro e Sul, em quatro horários: 8, 10, 14 e 16 horas.
- gere todos os pares rota–horário, agrupados por rota;
- escreva a sequência exata dos doze pares;
- inverta os laços e descreva o que muda;
- conte as execuções sem executar o código;
- altere a regra para que a primeira rota tenha dois horários, a segunda três e a terceira quatro;
- interrompa toda a busca ao encontrar
Centro–14usando uma função; - teste rota vazia, horários vazios e alvo ausente.
Explique em uma frase a responsabilidade de cada laço e registre onde a variável interna reinicia.
O que você deve guardar
O laço externo mantém um contexto enquanto o interno completa seu percurso. Por isso, a ordem dos níveis determina a ordem dos pares, e cada variável deve representar claramente a dimensão que controla.
Multiplique as quantidades somente quando o limite interno for constante para cada volta externa; caso contrário, conte e some cada percurso. Verifique término e interrupções nível por nível, lembrando que break sem rótulo normalmente encerra apenas o laço mais próximo. No próximo módulo, entenda por que dividir um algoritmo em partes para reduzir o contexto necessário em cada etapa e concentrar responsabilidades.
Referências
- Microsoft Learn — Branches and loops: create nested loops. Acesso em 11 set. 2026.
- MDN Web Docs — Loops and iteration. Acesso em 11 set. 2026.
- MDN Web Docs —
break. Acesso em 11 set. 2026. - MIT OpenCourseWare — Introduction to CS and Programming Using Python, Lecture 22: Big Oh and Theta. Acesso em 11 set. 2026.