Estruturas de Repetição
Laços são como dar voltas numa pista de corrida — continue até chegar à linha de chegada. Quando a condição é atendida, você para. Com laços, programas podem fazer mais do que apenas executar uma vez.
O laço while
while é o laço mais básico: verifica a condição primeiro, executa o corpo do laço se for verdadeira, depois verifica novamente, repetindo até que a condição se torne falsa.
#include <stdio.h>
int main(void) {
int count = 1;
while (count <= 5) {
printf("Lap %d\n", count);
count++;
}
printf("Done!\n");
return 0;
}
Lap 1
Lap 2
Lap 3
Lap 4
Lap 5
Done!
count++). Caso contrário, você terá um laço infinito e o programa nunca parará.
Quando usar while
Quando o número de iterações é incerto e depende de uma condição em tempo de execução, while é a escolha mais natural. Por exemplo, ler entradas até um valor específico:
#include <stdio.h>
int main(void) {
int sum = 0;
int num = 0;
printf("Enter positive integers to sum, 0 to finish: ");
scanf("%d", &num);
while (num != 0) {
sum += num;
scanf("%d", &num);
}
printf("Sum: %d\n", sum);
return 0;
}
Enter positive integers to sum, 0 to finish: 10 20 30 0
Sum: 60
O laço do-while
do-while executa o corpo do laço primeiro, depois verifica a condição. Isso garante que o corpo execute pelo menos uma vez, o que é a principal diferença em relação ao while.
#include <stdio.h>
int main(void) {
int num;
do {
printf("Enter a number 1-10: ");
scanf("%d", &num);
} while (num < 1 || num > 10);
printf("You entered: %d\n", num);
return 0;
}
Enter a number 1-10: 15
Enter a number 1-10: 0
Enter a number 1-10: 7
You entered: 7
do-while não deve ser omitido: } while (condição); Esquecer o ponto e vírgula causará erro de compilação.
Escolhendo entre while e do-while
- Precisa de pelo menos uma execução ->
do-while(ex.: validação de entrada) - Possivelmente zero execuções ->
while(ex.: busca onde nada pode ser encontrado)
O laço for
for combina inicialização, verificação de condição e atualização no cabeçalho, tornando-se a forma de laço mais comumente usada.
for (inicialização; condição; atualização) {
corpo do laço;
}
#include <stdio.h>
int main(void) {
for (int i = 1; i <= 5; i++) {
printf("%d ", i);
}
printf("\n");
return 0;
}
1 2 3 4 5
Fluxo de execução do for
- Executa a inicialização (apenas uma vez)
- Verifica a condição — se falsa, sai do laço
- Executa o corpo do laço
- Executa a atualização
- Volta ao passo 2
Flexibilidade do for
Todas as três partes do for podem ser omitidas, mas os pontos e vírgulas devem permanecer:
#include <stdio.h>
int main(void) {
int i = 1;
for (; i <= 5; ) {
printf("%d ", i);
i++;
}
printf("\n");
return 0;
}
Omitir a condição cria um laço infinito: for (;;) {} é equivalente a while (1) {}.
for — a variável do laço, a condição de parada e o método de atualização ficam todos visíveis de uma vez, tornando mais difícil escrever acidentalmente um laço infinito.
Considerações de escopo
C99 permite declarar variáveis na inicialização do for. Essas variáveis têm escopo limitado apenas ao laço for:
#include <stdio.h>
int main(void) {
for (int i = 0; i < 3; i++) {
printf("i = %d\n", i);
}
return 0;
}
Após o término do laço, i não é mais acessível. Se você precisar usar i fora do laço, declare-o antes do for.
Laços aninhados
Um laço dentro de outro é um laço aninhado. Cada iteração do laço externo executa completamente o laço interno.
Imprimindo um retângulo de asteriscos
#include <stdio.h>
int main(void) {
int rows = 3;
int cols = 5;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("* ");
}
printf("\n");
}
return 0;
}
* * * * *
* * * * *
* * * * *
Tabuada
#include <stdio.h>
int main(void) {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
printf("%d*%d=%-4d", j, i, i * j);
}
printf("\n");
}
return 0;
}
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
O comando break
break sai imediatamente do laço atual (apenas um nível). As iterações restantes são ignoradas.
#include <stdio.h>
int main(void) {
for (int i = 1; i <= 10; i++) {
if (i == 5) {
break;
}
printf("%d ", i);
}
printf("\nStopped at 5\n");
return 0;
}
1 2 3 4
Stopped at 5
Encontrando o primeiro elemento que atende a uma condição
#include <stdio.h>
int main(void) {
int nums[] = {3, 7, 2, 9, 5, 1};
int target = 9;
int found = 0;
for (int i = 0; i < 6; i++) {
if (nums[i] == target) {
printf("Found %d at index %d\n", target, i);
found = 1;
break;
}
}
if (!found) {
printf("%d not found\n", target);
}
return 0;
}
Found 9 at index 3
O comando continue
continue ignora os comandos restantes da iteração atual e salta para a próxima iteração (retornando à verificação da condição ou passo de atualização).
#include <stdio.h>
int main(void) {
for (int i = 1; i <= 10; i++) {
if (i % 3 == 0) {
continue;
}
printf("%d ", i);
}
printf("\nMultiples of 3 skipped\n");
return 0;
}
1 2 4 5 7 8 10
Multiples of 3 skipped
continue em laços while e do-while, certifique-se de que o comando de atualização venha antes do continue, ou você pode criar um laço infinito.
Padrões comuns de laços
Padrão de contagem
Conte quantos elementos satisfazem uma condição:
#include <stdio.h>
int main(void) {
int nums[] = {12, 45, 3, 67, 89, 23, 56};
int count = 0;
for (int i = 0; i < 7; i++) {
if (nums[i] > 50) {
count++;
}
}
printf("Numbers greater than 50: %d\n", count);
return 0;
}
Numbers greater than 50: 3
Padrão de acumulação
Some uma série de valores:
#include <stdio.h>
int main(void) {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
printf("Sum from 1 to 100: %d\n", sum);
return 0;
}
Sum from 1 to 100: 5050
Padrão de busca
Encontre o primeiro elemento que atende a uma condição, depois saia com break:
Veja o exemplo anterior de break.
Padrão de percurso
Processe cada elemento de um vetor sequencialmente:
#include <stdio.h>
int main(void) {
int scores[] = {85, 92, 78, 96, 61};
int len = 5;
for (int i = 0; i < len; i++) {
printf("Student%d: %d %s\n", i + 1, scores[i], scores[i] >= 60 ? "Pass" : "Fail");
}
return 0;
}
Student1: 85 Pass
Student2: 92 Pass
Student3: 78 Pass
Student4: 96 Pass
Student5: 61 Pass
Laços infinitos e como evitá-los
Um laço infinito é aquele cuja condição é sempre verdadeira. Laços infinitos intencionais usam for(;;) ou while(1), com break interno para sair:
#include <stdio.h>
int main(void) {
int num;
while (1) {
printf("Enter a number (0 to quit): ");
scanf("%d", &num);
if (num == 0) {
break;
}
printf("You entered: %d\n", num);
}
printf("Goodbye!\n");
return 0;
}
Laços infinitos não intencionais geralmente ocorrem porque a variável do laço nunca é atualizada ou é atualizada na direção errada:
int i = 0;
while (i < 10) {
printf("%d", i);
}
Exemplo
Imprima um triângulo retângulo usando laços aninhados:
#include <stdio.h>
int main(void) {
int n = 5;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
printf("* ");
}
printf("\n");
}
return 0;
}
*
* *
* * *
* * * *
* * * * *
Exemplo
Encontre o máximo divisor comum de dois inteiros positivos usando o algoritmo de Euclides, demonstrando um laço while com número incerto de iterações:
#include <stdio.h>
int main(void) {
int a = 48, b = 18;
int orig_a = a, orig_b = b;
while (b != 0) {
int temp = a % b;
a = b;
b = temp;
}
printf("GCD of %d and %d is %d\n", orig_a, orig_b, a);
return 0;
}
GCD of 48 and 18 is 6
Escolhendo entre os três laços
| Situação | Recomendação |
|---|---|
| Número fixo de iterações | for |
| Deve executar pelo menos uma vez | do-while |
| Número incerto de iterações | while |
| Menu interativo | do-while + switch |
❓ Perguntas Frequentes
P: Devo usar
forouwhile? R: Useforquando o número de iterações é conhecido, ewhilequando não é. Essa é a diretriz mais amplamente aceita.
P: O
breakpode sair de múltiplos níveis de laços? R: Não. Obreaksó sai do laço mais interno. Para sair de múltiplos níveis, use uma variável de sinalização com verificação no laço externo, ougoto(não recomendado, mas às vezes prático).
P: Qual é melhor:
for(;;)ouwhile(1)? R: São funcionalmente equivalentes.while(1)é mais legível;for(;;)é estilo tradicional de C. Escolha com base nas convenções da sua equipe.
P: É certo usar
i,j,kcomo variáveis de laço? R: Em laços simples, essa é uma convenção amplamente aceita. No entanto, quando a variável tem significado de negócio (ex.:row,col,student_index), um nome descritivo é melhor.
📖 Resumo
whileverifica antes de executar,do-whileexecuta antes de verificar,forconcentra os três elementos no cabeçalhoforé a estrutura de laço mais usada para iterações com número fixo- A contagem total de iterações em laços aninhados é o produto da contagem de cada nível — cuidado com o desempenho
breaksai do laço atual,continueignora a iteração atual — ambos afetam apenas o laço mais interno- Evite laços infinitos não intencionais: garanta que a variável do laço seja atualizada corretamente e na direção certa
📝 Exercícios
- Escreva um programa usando um laço
forpara calcular a soma dos fatoriais: 1! + 2! + 3! + ... + 10!. - Escreva um programa usando laços aninhados para imprimir um triângulo retângulo invertido (5 linhas, 5 asteriscos na linha 1, 1 asterisco na linha 5).
- Escreva um programa que leia um inteiro positivo e imprima seus dígitos em ordem inversa (ex.: entrada 1234 saída 4 3 2 1).



