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 com o truque do sizeof, laços aninhados, laços infinitos e os bugs 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

if e switch escolhem um ramo e o executam uma vez. Programas reais precisam fazer coisas repetidamente: imprimir cada pontuação, somar uma lista de números, desenhar dez linhas de uma grade, testar cada caractere de uma string. O laço for é o burro de carga do C para repetir código um número conhecido de vezes, com um contador que você controla.

Tudo de que um laço for precisa fica em um cabeçalho compacto, então "quantas vezes, e como" é visível em uma única linha.

O cabeçalho de três partes

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

for (inicializador; condicao; atualizacao) {
    /* corpo - executa enquanto a condição for diferente de zero */
}

Elas executam em uma ordem específica, e conhecê-la explica todo laço for que você vai ler na vida:

  1. O inicializador executa uma vez, antes de tudo.
  2. A condição é testada. Se for zero, o laço termina imediatamente.
  3. O corpo executa.
  4. A atualização executa.
  5. Volta ao passo 2.

Percorra o laço acima com essa lista: int i = 0 executa uma vez. 0 < 5 vale, então o corpo imprime i = 0 e i++ faz i valer 1. A condição é testada de novo, e assim por diante. Quando i chega a 5 o teste falha, o corpo é pulado e fim é impresso. O corpo executou exatamente cinco vezes, com i assumindo os valores de 0 a 4.

Duas consequências seguem direto disso. A condição é verificada antes da primeira passagem, então um laço cuja condição já começa falsa executa zero vezes - for (int i = 10; i < 5; i++) nunca entra no corpo. E a atualização executa depois do corpo, então i ainda guarda o valor antigo durante todo o corpo.

Declarar o contador dentro do cabeçalho (int i = 0) é legal desde o C99 e é o padrão certo: i então existe só dentro do laço, não pode colidir com nada depois dele, e cada laço da função pode reutilizar o nome à vontade.

Contar para cima, para baixo e em passos

A atualização não se limita a i++. Conte para baixo, avance de qualquer quantidade, ou dobre a cada passagem:

Combine a condição com a atualização. Contar para cima combina com < ou <=; contar para baixo combina com > ou >=. Errar esse pareamento é como se escreve um laço que nunca termina.

Note que o segundo laço usa <= 10 porque 10 é um valor que queremos incluir, enquanto o primeiro exemplo usou < 5 porque 5 não é. É nessa escolha que nascem os bugs de deslocamento por um, então faça-a conscientemente: i < n executa n vezes começando em 0; i <= n executa n + 1 vezes.

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ê.

Duas coisas para levar daqui.

O truque do sizeof. sizeof(notas) é o tamanho do array inteiro em bytes, e sizeof(notas[0]) é o tamanho de um elemento, então o quociente é a quantidade de elementos. Ele se adapta automaticamente quando você acrescenta um elemento, coisa que um 5 fixo no código não faz. O problema - e é grande - é que isso só funciona onde o próprio array está em escopo. Passe o array para uma função e ele decai para um ponteiro, então sizeof lá dá o tamanho de um ponteiro. Dentro de uma função, sempre receba o tamanho como um parâmetro separado.

A condição é i < n, nunca i <= n. Um array de cinco elementos tem índices válidos de 0 a 4. Ler notas[5] é comportamento indefinido: pode imprimir lixo, travar, ou parecer funcionar enquanto corrompe silenciosamente outra coisa. C não faz verificação de limites nenhuma, então isso é inteiramente responsabilidade sua.

Percorrer um array de trás para frente é a mesma ideia ao contrário:

Comece em n - 1 (o último índice válido) e pare em 0 inclusive - daí o >=, não >. Mantenha i como um int com sinal aqui; a próxima seção explica por quê.

Laços aninhados

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

O laço externo fixa uma linha; o laço interno varre cada coluna daquela linha; o printf("\n") depois do laço interno encerra a linha. Mova essa quebra de linha para dentro do laço interno e a tabela inteira vira uma coluna só - vale a pena testar, porque torna a estrutura do aninhamento concreta.

Dê nomes distintos aos contadores. linha/coluna ou i/j servem; reutilizar i para os dois oculta o contador externo e produz resultados desconcertantes. E fique de olho no custo: um laço de n dentro de outro de n executa o corpo n * n vezes, então um par de laços de 1.000 iterações são um milhão de passagens.

Aqui está um laço aninhado fazendo trabalho de verdade - um triângulo de estrelas, em que o limite do laço interno depende do contador externo:

break e continue

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

O primeiro laço para no momento em que encontra 7 e nunca verifica os 93 valores restantes. O segundo usa continue para pular a impressão nos números pares; o i++ do cabeçalho ainda executa, então o laço continua avançando. Tem muito mais sobre os dois em break e continue, inclusive como escapar de um laço aninhado, coisa que um único break não faz.

Laços infinitos e partes vazias

Todas as três partes do cabeçalho são opcionais. Deixe a condição de fora e ela é tratada como permanentemente verdadeira:

for (;;) {
    /* executa para sempre - saia com break ou return */
}

for (;;) é o laço infinito idiomático do C, e os pontos e vírgulas continuam obrigatórios. Não é um erro, desde que algo lá dentro possa dar break, return ou exit - laços de eventos e laços do tipo "continue perguntando até a entrada ser válida" são escritos exatamente assim.

As outras partes também podem ser omitidas. Se o contador já existe, pule o inicializador; se o corpo o avança, pule a atualização:

int i = 0;
for (; i < n; ) {
    /* ... */
    i += passo;
}

Isso é legal, mas se lê pior do que o laço while que na verdade é. Prefira um for quando o contador, seu limite e seu passo pertencem juntos ao cabeçalho, e um while quando não pertencem.

O operador vírgula em um cabeçalho

O inicializador e a atualização podem conter várias expressões separadas por vírgula, que é como você opera dois contadores ao mesmo tempo:

int i = 0, j = len - 1 declara os dois contadores, e i++, j-- avança os dois. Esse é o operador vírgula, que avalia seus operandos em ordem. Use-o para contadores genuinamente paralelos; enfiar trabalho não relacionado em um cabeçalho só esconde esse trabalho.

Armadilhas comuns

Um punhado de armadilhas responde pela maioria dos bugs de laço for em C.

Deslocamento por um. i <= n em um array baseado em zero lê um elemento além do fim. Use i < n para "n vezes começando em 0".

Um ponto e vírgula depois do cabeçalho. Isso compila e quase nunca é o que você quis dizer:

/* BUG: o corpo do laco e a instrucao vazia; o printf executa uma vez */
for (int i = 0; i < 5; i++);
{
    printf("%d\n", i);
}

O ; vira o corpo, então o laço gira cinco vezes sem fazer nada e as chaves abaixo executam uma vez, como um bloco comum. O gcc -Wall avisa sobre isso.

Contadores sem sinal contando para baixo. Isto é um laço infinito:

/* BUG: um valor unsigned nunca e < 0 */
for (size_t i = n - 1; i >= 0; i--) {
    processa(a[i]);
}

i >= 0 é sempre verdadeiro para um tipo sem sinal. Quando i chega a 0, i-- dá a volta para um número positivo enorme e o laço segue adiante por memória que não lhe pertence. Use um int com sinal para contagens decrescentes, ou escreva a condição como for (size_t i = n; i-- > 0; ), que decrementa e testa em um passo só e para corretamente no zero.

Modificar o contador em dois lugares. Mudar i dentro do corpo além do cabeçalho torna a contagem de iterações imprevisível. Escolha um lugar só.

Contadores de ponto flutuante. for (double x = 0.0; x != 1.0; x += 0.1) pode nunca terminar, porque 0.1 não tem representação binária exata e a soma passa de 1.0 sem acertá-lo. Faça o laço com uma contagem inteira e calcule o valor dentro:

for (int i = 0; i <= 10; i++) {
    double x = i / 10.0;
    /* ... */
}

Mudar o tamanho de um array enquanto o percorre. A condição i < n relê n a cada passagem, então se o corpo encolhe a coleção, ajuste o índice deliberadamente em vez de deixar os dois se desencontrarem.

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++) { printf("%d\n", i); }. Isso executa o corpo cinco vezes, com i assumindo os valores de 0 a 4, e para assim que a condição se torna falsa.

Como percorrer um array em C?

Conte um índice de 0 até (mas sem incluir) o tamanho: for (int i = 0; i < n; i++) { soma += a[i]; }. Para um array declarado na mesma função você pode calcular o tamanho com sizeof(a) / sizeof(a[0]); depois que o array foi passado para uma função esse truque não funciona mais, então passe o tamanho como parâmetro.

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

Esse é o bug de deslocamento por um (off-by-one). Em um array baseado em zero de tamanho n, os índices válidos vão de 0 a n - 1, então i <= n executa uma iteração extra e lê além do fim - comportamento indefinido. O padrão seguro é i < n.

Dá para declarar a variável do laço dentro do for em C?

Sim, desde o C99: for (int i = 0; i < n; i++). A variável então existe só dentro do laço, que é o que você quer. Compile com gcc -std=c99 ou mais recente (GCC e clang modernos usam C17 por padrão, então simplesmente funciona); o estilo antigo, do C89, declarava i antes do laço.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR