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:
- O inicializador executa uma vez, antes de tudo.
- A condição é testada. Se for zero, o laço termina imediatamente.
- O corpo executa.
- A atualização executa.
- 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.