Menu

Laço for em C++: sintaxe, exemplos e erros comuns

Como repetir código com o laço for do C++: o cabeçalho de três partes, contar para cima e para baixo, percorrer arrays, aninhar, break e continue, além dos erros de deslocamento por um e de tipos sem sinal que pegam todo mundo.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Por que um laço for

Um switch escolhe um ramo para executar uma única vez. Mas programas reais precisam fazer algo repetidamente: imprimir cada pontuação, somar uma lista de números, desenhar 10 linhas de uma grade. O laço for é o burro de carga do C++ para repetir código um número conhecido de vezes, com um contador embutido que você controla.

Tudo de que um laço for precisa vive em um cabeçalho compacto, então toda a história de "quantas vezes e como" fica visível num relance.

O cabeçalho de três partes

O cabeçalho de um laço for tem três partes separadas por ponto e vírgula: um inicializador, uma condição e uma atualização.

for (initializer; condition; update) {
    // corpo: executa enquanto a condição for verdadeira
}

Eles executam em uma ordem específica: o inicializador executa uma vez no início; depois a condição é verificada antes de cada iteração; o corpo executa só se a condição for true; e a atualização executa no fim de cada iteração, logo antes de a condição ser verificada de novo.

Aqui int i = 0 executa uma vez. Depois i < 5 é verificado: enquanto vale, o corpo imprime e i++ incrementa o contador. Quando i chega a 5 a condição é false, então o laço sai e done é impresso. O corpo executa exatamente 5 vezes, com i assumindo os valores 0 a 4.

Declarar o contador dentro do cabeçalho (int i = 0) mantém i com escopo limitado ao laço: ele não existe depois da chave de fechamento, que é exatamente o que você quer.

Contar para cima, para baixo e em passos

A parte de atualização não se limita a i++. Você pode contar para baixo, avançar em qualquer quantidade ou percorrer o índice de um array.

O primeiro laço executa enquanto i > 0, decrementando a cada vez, então imprime 5 4 3 2 1. O segundo soma 2 a cada passagem e usa <= 10 porque 10 é um valor que queremos incluir. Combine sua condição com sua atualização: contar para baixo combina com > ou >=, contar para cima com < ou <=.

Percorrer um array

O uso mais comum de um laço de contagem é percorrer um array por índice. O contador funciona também como a posição que você lê.

Note que a condição é i < n, não i <= n. Um array de 5 elementos tem índices válidos de 0 a 4; o índice 5 está além do fim. Ler scores[5] é comportamento indefinido: pode imprimir lixo, travar, ou parecer funcionar e corromper a memória silenciosamente. O padrão i < n é o padrão seguro para qualquer array baseado em zero.

Se você só precisa dos valores e não do índice, um for baseado em intervalo é mais limpo. Recorra ao laço indexado clássico quando realmente precisar da posição.

break e continue

Duas palavras-chave permitem mudar o fluxo no meio do laço. break sai do laço imediatamente; continue pula o resto da iteração atual e salta para a atualização.

O primeiro laço para no momento em que encontra 7 e nunca verifica o resto. O segundo usa continue para pular a impressão do corpo sempre que i for par: a atualização i++ ainda executa, então o laço continua avançando. Uma armadilha sutil: continue salta para a atualização, então se você algum dia depender de continue dentro de um laço cujo contador é atualizado dentro do corpo em vez do cabeçalho, você pode pular essa atualização por acidente e girar para sempre.

Laços aninhados

Coloque um for dentro de outro para trabalhar com grades, tabelas ou pares. O laço interno executa por completo a cada passo individual do laço externo.

Isso imprime uma grade de multiplicação 3x3. O laço externo fixa uma row, o laço interno varre cada col daquela linha, e então uma quebra de linha encerra a linha. Dê nomes distintos aos contadores (row/col, não i/i): reutilizar um nome oculta o externo e produz bugs desconcertantes. Fique de olho no custo também: aninhar um laço de n dentro de outro de n executa o corpo n * n vezes, o que acumula rápido.

Armadilhas comuns

Algumas armadilhas explicam a maioria dos bugs de laços for em C++:

  • Deslocamento por um: i <= n com um tamanho baseado em zero lê um elemento além do fim. Use i < n.
  • Underflow sem sinal: contar para baixo com um tipo sem sinal nunca fica negativo. for (size_t i = n - 1; i >= 0; i--) repete para sempre, porque i >= 0 é sempre verdadeiro para um valor sem sinal: quando i é 0, i-- dá a volta para um número positivo enorme. Use um int com sinal para contagens decrescentes, ou reescreva a condição.
  • Modificar o contador dentro do corpo: mudar i no corpo além do cabeçalho torna a contagem do laço imprevisível. Escolha um único lugar.
// BUG: infinite loop - unsigned i is never < 0
for (size_t i = n - 1; i >= 0; i--) {
    process(arr[i]);
}

Contadores de ponto flutuante são outro perigo silencioso: for (double x = 0.0; x != 1.0; x += 0.1) pode nunca atingir exatamente 1.0 porque 0.1 não pode ser armazenado com precisão. Faça o laço com uma contagem inteira e calcule o valor dentro, ou use < em vez de !=.

Próximo: laços while

O laço for brilha quando você conhece a contagem de antemão. Mas às vezes você precisa repetir até uma condição mudar (ler entrada até o fim do arquivo, tentar de novo até dar certo) sem um número fixo de passos. Esse é o trabalho do laço while, que reduz o cabeçalho a apenas uma condição. É a próxima página.

Perguntas frequentes

Como se escreve um laço for em C++?

Coloque três partes no cabeçalho separadas por ponto e vírgula: um inicializador, uma condição e uma atualização. for (int i = 0; i < 5; i++) { cout << i; } executa o corpo com i assumindo os valores 0, 1, 2, 3, 4. O laço para assim que a condição se torna false.

Qual é a diferença entre um laço for e um laço for baseado em intervalo em C++?

Um for clássico te dá um contador de índice que você controla (for (int i = 0; i < n; i++)), de que você precisa quando quer a posição ou quer avançar de um jeito personalizado. Um for baseado em intervalo (for (int x : v)) esconde o índice e simplesmente entrega cada elemento: mais limpo quando você só precisa dos valores.

Por que meu laço for em C++ executa uma vez a mais ou uma vez a menos?

Esse é o clássico erro de deslocamento por um (off-by-one). Usar <= em vez de < com um tamanho baseado em zero executa uma iteração a mais e lê além do fim do array; usar < quando você queria incluir o último valor o deixa uma vez curto. Para um array de tamanho n, o padrão seguro é for (int i = 0; i < n; i++).

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR