Laço for em C
LidoA aula aborda o laço for em C, detalhando sua estrutura, os componentes de inicialização, condição e incremento, o uso de break e continue, e a criação de loops aninhados. Inclui exemplos práticos, referências e exercícios com respostas.
O laço for é uma das estruturas de repetição mais utilizadas na linguagem C, especialmente quando o número de iterações é conhecido ou pode ser facilmente determinado. Ele permite executar um bloco de código várias vezes, controlando a variável de controle de forma compacta e legível. Nesta aula, vamos explorar detalhadamente a sintaxe do for, seus componentes, variações com break e continue, e como criar loops aninhados para resolver problemas mais complexos.
Dominar o laço for é essencial para qualquer programador em C, pois ele aparece em algoritmos de ordenação, busca, manipulação de matrizes, processamento de dados e muito mais. Vamos começar pela estrutura básica e depois avançar para técnicas mais avançadas, com exemplos práticos que você pode testar em seu compilador.
Estrutura
A sintaxe do laço for em C é composta por três partes principais entre parênteses, separadas por ponto e vírgula: inicialização, condição e incremento. A estrutura é a seguinte:
for (inicialização; condição; incremento) {
// bloco de código a ser repetido
}
O fluxo de execução ocorre assim: primeiro, a inicialização é executada (uma única vez). Em seguida, a condição é avaliada; se for verdadeira, o bloco de código é executado. Depois da execução do bloco, o incremento é executado e a condição é avaliada novamente. Esse ciclo continua até que a condição se torne falsa, momento em que o laço termina e o programa prossegue com a próxima instrução após o laço.
É importante notar que qualquer uma das três partes pode ser omitida, mas os ponto e vírgula devem permanecer. Por exemplo, um laço infinito pode ser criado com for (;;), mas isso raramente é usado sem uma forma de saída (como break). O bloco de código pode conter uma única instrução (sem chaves) ou múltiplas instruções entre chaves.
// Exemplo: imprimir números de 0 a 4
#include <stdio.h>
int main() {
for (int i = 0; i < 5; i++) {
printf("%d\n", i);
}
return 0;
}
Neste exemplo, a variável i é inicializada com 0, a condição é i < 5 e o incremento é i++. O resultado será a impressão dos números 0, 1, 2, 3 e 4, cada um em uma linha.
Inicialização, condição, incremento
Cada parte do laço for tem um papel específico e pode ser personalizada de acordo com a necessidade do algoritmo. Vamos analisar cada uma delas em detalhes.
Inicialização
A inicialização é executada apenas uma vez, antes de o laço começar. Normalmente, ela define a variável de controle com um valor inicial. Em C moderno (padrão C99 em diante), é possível declarar a variável diretamente dentro da inicialização, como vimos no exemplo anterior (int i = 0). Essa variável tem escopo local ao laço, ou seja, não pode ser acessada fora dele.
// Inicialização com declaração da variável
for (int i = 10; i > 0; i--) {
printf("%d ", i);
}
// i não está acessível aqui
Se você precisar usar a variável após o laço, declare-a antes do for:
int i;
for (i = 0; i < 10; i++) {
// ...
}
printf("Valor final de i: %d\n", i); // 10
Também é possível inicializar múltiplas variáveis separando-as por vírgula, como for (i = 0, j = 10; ...), mas isso pode prejudicar a legibilidade.
Condição
A condição é uma expressão relacional ou lógica que é avaliada antes de cada iteração. Se a condição for verdadeira (diferente de zero), o bloco é executado; se for falsa (zero), o laço é encerrado. A condição é testada no início de cada iteração, inclusive na primeira. Portanto, se a condição já for falsa no início, o bloco nunca será executado.
// Condição que nunca é verdadeira
for (int i = 5; i < 0; i++) {
printf("Nunca imprimirá\n");
}
A condição pode ser qualquer expressão válida em C, incluindo chamadas de função, mas é comum usar comparações simples. Cuidado com erros de digitação como usar = em vez de ==, pois isso pode causar um loop infinito ou comportamento inesperado.
Incremento
O incremento é executado ao final de cada iteração, após o bloco de código. Ele atualiza a variável de controle, geralmente incrementando ou decrementando. Pode ser qualquer expressão, não apenas i++. Por exemplo, você pode usar i += 2 para avançar de dois em dois, ou i *= 2 para dobrar o valor a cada iteração.
// Imprimir números pares de 0 a 10
for (int i = 0; i <= 10; i += 2) {
printf("%d ", i);
}
// Saída: 0 2 4 6 8 10
É importante que o incremento eventualmente torne a condição falsa; caso contrário, teremos um loop infinito. Por exemplo, se você esquecer o incremento, a condição permanece verdadeira para sempre.
break e continue
Dentro do laço for, você pode usar as instruções break e continue para controlar o fluxo de execução de maneira mais refinada.
break
A instrução break encerra imediatamente o laço mais interno em que está contida, transferindo o controle para a próxima instrução após o laço. Isso é útil quando você deseja interromper a repetição antes que a condição se torne falsa, por exemplo, ao encontrar um valor específico.
// Procurar o número 7 em um intervalo
for (int i = 0; i < 10; i++) {
if (i == 7) {
printf("Encontrado: %d\n", i);
break; // sai do laço
}
}
// Após o break, o controle vem para cá
No exemplo acima, quando i chega a 7, o laço é interrompido, e as iterações seguintes (8 e 9) não são executadas. O break é especialmente útil em loops infinitos ou quando a condição de saída depende de cálculos complexos.
continue
A instrução continue pula o restante do bloco de código da iteração atual e vai diretamente para o incremento, iniciando a próxima iteração (se a condição ainda for verdadeira). Ela não encerra o laço, apenas ignora as instruções restantes da iteração corrente.
// Imprimir apenas números ímpares de 0 a 9
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
continue; // pula para o incremento
}
printf("%d ", i);
}
// Saída: 1 3 5 7 9
No exemplo, quando i é par, a instrução continue faz com que o printf seja ignorado, e o laço prossegue com a próxima iteração. O continue é útil para filtrar valores sem precisar de uma estrutura if-else complexa.
É importante lembrar que break e continue afetam apenas o laço mais interno. Em loops aninhados, eles atuam no nível em que estão escritos.
Loops aninhados
Loops aninhados são laços for dentro de outros laços. Eles são comuns quando é necessário percorrer estruturas bidimensionais, como matrizes, ou quando precisamos combinar iterações de múltiplas variáveis. O laço externo controla as iterações principais, e o laço interno é executado completamente para cada iteração do externo.
// Exemplo: imprimir uma tabuada de multiplicação (1 a 5)
#include <stdio.h>
int main() {
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
printf("%d x %d = %d\t", i, j, i * j);
}
printf("\n"); // nova linha após cada linha da tabela
}
return 0;
}
Esse código gera uma tabela 5x5 com as multiplicações. O laço externo (i) representa a primeira linha e varia de 1 a 5; para cada valor de i, o laço interno (j) percorre todos os valores de 1 a 5, imprimindo o produto, e depois o laço externo imprime uma nova linha.
Loops aninhados podem ter qualquer profundidade, mas é importante manter o código legível. Um exemplo clássico é o preenchimento de uma matriz:
// Preencher uma matriz 3x3 com valores sequenciais
int matriz[3][3];
int contador = 1;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
matriz[i][j] = contador++;
}
}
Quando usar loops aninhados, preste atenção à complexidade: se o laço externo tem n iterações e o interno m, o total de execuções do bloco interno será n * m. Isso pode se tornar ineficiente para grandes valores, então avalie se há alternativas.
Uma aplicação comum de loops aninhados é a impressão de padrões, como triângulos de asteriscos:
// Imprimir um triângulo retângulo de altura 5
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
printf("*");
}
printf("\n");
}
Nesse caso, o laço interno depende do valor do externo, criando um padrão crescente.
Boas práticas e observações finais
Ao utilizar o laço for, siga estas recomendações para escrever código mais claro e evitar erros comuns:
- Declare a variável de controle dentro do próprio
for(C99 ou superior) para limitar seu escopo e evitar conflitos de nomes. - Use nomes significativos para a variável de controle, como
i,jpara índices, mas evite nomes muito vagos em loops complexos. - Evite modificar a variável de controle dentro do corpo do laço, a menos que seja intencional; isso pode dificultar a compreensão.
- Prefira o
forquando o número de iterações for conhecido; para loops baseados em condições, owhilepode ser mais adequado. - Cuidado com loops infinitos: sempre verifique se a condição pode se tornar falsa.
- Em loops aninhados, mantenha a indentação consistente para melhorar a legibilidade.
- Teste os limites do laço (primeira e última iteração) para garantir que a condição está correta.
O laço for é uma ferramenta poderosa e versátil. Com a prática, você aprenderá a usá-lo de forma eficiente em diversas situações.
Referências
- cppreference.com - for loop
- GNU C Manual - The for Statement
- Microsoft C Language Reference - for Statement
- IBM Documentation - for statement
- TutorialsPoint - C Loop Control
- GeeksforGeeks - C for Loop
Exercícios
-
Escreva um programa em C que use um laço
forpara imprimir todos os números inteiros de 1 a 20, mas que pule os múltiplos de 3. Utilizecontinuepara essa tarefa.✓ Resposta:#include <stdio.h> int main() { for (int i = 1; i <= 20; i++) { if (i % 3 == 0) { continue; } printf("%d ", i); } printf("\n"); return 0; } -
Crie um código que use um laço
forpara calcular a soma dos números pares entre 1 e 100 (inclusive). Imprima o resultado.✓ Resposta:#include <stdio.h> int main() { int soma = 0; for (int i = 2; i <= 100; i += 2) { soma += i; } printf("Soma dos pares de 1 a 100: %d\n", soma); return 0; } -
Escreva um programa que utilize um laço
foraninhado para imprimir um triângulo de números, onde cada linha contém números de 1 até o número da linha. Exemplo para altura 5:1 12 123 1234 12345✓ Resposta:#include <stdio.h> int main() { int altura = 5; for (int i = 1; i <= altura; i++) { for (int j = 1; j <= i; j++) { printf("%d", j); } printf("\n"); } return 0; } -
Utilizando
break, escreva um programa que percorra os números de 1 a 100 e pare ao encontrar o primeiro número que seja divisível por 7 e por 9 simultaneamente. Imprima esse número.✓ Resposta:#include <stdio.h> int main() { for (int i = 1; i <= 100; i++) { if (i % 7 == 0 && i % 9 == 0) { printf("Encontrado: %d\n", i); break; } } return 0; } -
Escreva um programa que use um laço
forpara gerar os primeiros 10 termos da sequência de Fibonacci (0, 1, 1, 2, 3, 5, 8, 13, 21, 34). Dica: mantenha duas variáveis para os dois últimos termos.✓ Resposta:#include <stdio.h> int main() { int a = 0, b = 1; printf("%d %d ", a, b); for (int i = 2; i < 10; i++) { int proximo = a + b; printf("%d ", proximo); a = b; b = proximo; } printf("\n"); return 0; }