Semana 03 — Estruturas de repetição¶
Nesta semana
Unidade 1 · Seg 24/08 · Qua 26/08 · Sex 28/08
Computadores são incansáveis: fazem a mesma coisa milhões de vezes sem reclamar. Nesta
semana você aprende a aproveitar isso com as estruturas de repetição (os
laços ou loops): while, do-while e for. Em vez de escrever a mesma instrução
cem vezes, você a escreve uma vez e diz ao computador quantas vezes (ou até
quando) repeti-la.
Junto com as condicionais da semana passada, os laços completam o controle de fluxo — e, a partir daqui, você já consegue resolver uma quantidade enorme de problemas. Digite e execute cada exemplo.
🎯 Objetivos de aprendizagem¶
Ao final desta semana, você deverá ser capaz de:
- identificar os três ingredientes de todo laço (inicialização, condição, atualização) e por que a ausência de qualquer um causa um laço infinito;
- escrever laços com
while,do-whileefore escolher o mais adequado a cada problema; - implementar os padrões fundamentais de contador e acumulador;
- ler dados até uma condição de parada (padrão sentinela);
- controlar a execução com
breakecontinue; - construir e rastrear laços aninhados, base para tabelas e (na Unidade 2) matrizes.
📖 Segunda — Estudo do conteúdo¶
1. Por que repetir?¶
Imagine escrever um programa para somar as notas de 100 alunos, ou imprimir a tabuada do 7, ou pedir uma senha até o usuário acertar. Sem repetição, você teria que copiar e colar a mesma instrução dezenas de vezes — inviável, e impossível quando o número de repetições só é conhecido durante a execução.
Um laço executa um bloco de instruções repetidamente, enquanto uma condição for verdadeira. É um dos recursos mais poderosos da programação.
flowchart TD
A["condição verdadeira?"] -->|sim| B["executa o corpo do laço"]
B --> A
A -->|não| C["sai do laço e continua"]
2. A anatomia de um laço: três ingredientes¶
Todo laço bem-comportado tem três elementos. Se algum falta ou está errado, o laço nunca termina (laço infinito) ou nem começa:
- Inicialização — preparar a variável de controle (ex.:
i = 1). - Condição de continuação — o teste que decide se repete (ex.:
i <= 5). - Atualização — modificar a variável a cada volta, para que a condição um dia fique
falsa (ex.:
i++).
Cada execução completa do corpo é chamada de iteração.
Laço infinito: o pesadelo do iniciante
Se você esquecer a atualização, a condição nunca muda e o programa trava:
int i = 1;
while (i <= 5) {
printf("%d\n", i);
// faltou o i++ -> i é sempre 1 -> repete para sempre!
}
Ctrl + C no terminal (ou feche a
janela no Code::Blocks). Depois, procure o ingrediente que faltou.
3. while — repita enquanto (teste no início)¶
O while testa a condição antes de cada iteração. Se já for falsa de saída, o corpo
não executa nenhuma vez.
int i = 1; // 1. inicialização
while (i <= 5) { // 2. condição
printf("%d ", i);
i++; // 3. atualização
}
// Saída: 1 2 3 4 5
Use while quando você não sabe de antemão quantas vezes vai repetir — a repetição
depende de uma condição que muda durante a execução.
4. do-while — execute e depois teste (teste no fim)¶
O do-while executa o corpo primeiro e só então avalia a condição. Consequência: o
corpo roda pelo menos uma vez, mesmo que a condição já comece falsa.
int opcao;
do {
printf("Digite um numero positivo: ");
scanf("%d", &opcao);
} while (opcao <= 0); // repete enquanto a entrada for inválida
É a escolha ideal para menus e validação de entrada: você precisa pedir o dado ao menos uma vez antes de poder testá-lo.
O ; obrigatório do do-while
Diferentemente das outras estruturas, o do-while termina com ponto e vírgula
depois da condição: } while (opcao <= 0);. Esquecê-lo é erro de compilação.
5. for — o laço de contagem¶
O for reúne os três ingredientes em uma única linha, na ordem
for (inicialização; condição; atualização). É a forma preferida quando você sabe
quantas vezes vai repetir.
Ordem de execução do for:
flowchart TD
I["inicialização (uma vez)"] --> C{"condição?"}
C -->|verdadeira| B["corpo do laço"]
B --> U["atualização"]
U --> C
C -->|falsa| F["fim"]
O for acima é equivalente ao while da seção 3 — apenas mais compacto e com os três
ingredientes juntinhos, o que facilita a leitura e reduz o risco de esquecer a atualização.
Variando o passo e a direção
O for não precisa contar de 1 em 1, nem para cima:
Curiosidade 💡 — declarar i dentro do for
Em C moderno (padrão C99 em diante, que usamos), você pode declarar a variável de
controle dentro do for: for (int i = 0; ...). Assim, i só existe dentro do
laço (seu escopo é o laço). Isso é uma boa prática: evita reaproveitar i sem
querer em outra parte do programa. Falaremos de escopo em detalhe na Semana 04.
6. Qual laço usar?¶
Os três laços são intercambiáveis (tudo que se faz com um dá para fazer com os outros), mas cada um tem seu ponto forte:
| Use… | Quando… | Exemplo típico |
|---|---|---|
for |
você sabe o número de repetições | percorrer de 1 a N, tabuada |
while |
repete enquanto uma condição valer, número de vezes desconhecido | ler até um valor sentinela |
do-while |
o corpo precisa rodar ao menos uma vez | menus, validação de entrada |
7. Padrões fundamentais: contador e acumulador¶
Dois padrões aparecem em praticamente todo programa com laço:
- Contador: uma variável que conta ocorrências (soma 1 quando algo acontece).
- Acumulador: uma variável que acumula um total (soma valores, multiplica, etc.).
Ambos precisam ser inicializados antes do laço:
#include <stdio.h>
int main(void) {
int n;
printf("Quantos numeros? ");
scanf("%d", &n);
int soma = 0; // acumulador (começa em 0)
for (int i = 0; i < n; i++) {
int valor;
scanf("%d", &valor);
soma += valor; // acumula
}
double media = (double) soma / n; // cast evita divisão inteira!
printf("Soma = %d, media = %.2f\n", soma, media);
return 0;
}
Inicialize acumuladores com o valor 'neutro'
- Para somar, comece em 0 (
soma = 0): somar 0 não muda nada. - Para multiplicar (ex.: fatorial), comece em 1 (
produto = 1): multiplicar por 1 não muda nada. Começar um produto em 0 daria sempre 0 — erro clássico!
8. O padrão sentinela: repetir até um valor de parada¶
Às vezes não sabemos quantos dados virão — repetimos até o usuário digitar um valor especial (a sentinela) que sinaliza o fim.
#include <stdio.h>
int main(void) {
int valor, soma = 0, quantidade = 0;
printf("Digite numeros (0 para encerrar):\n");
scanf("%d", &valor);
while (valor != 0) { // 0 é a sentinela
soma += valor;
quantidade++;
scanf("%d", &valor); // lê o próximo antes de testar de novo
}
if (quantidade > 0) {
printf("Soma = %d, media = %.2f\n", soma, (double) soma / quantidade);
} else {
printf("Nenhum numero informado.\n");
}
return 0;
}
Repare no padrão "ler antes, testar, e reler no fim do corpo" — é o que garante que a sentinela em si não entre na conta.
9. break e continue: desviando o fluxo do laço¶
break— abandona o laço imediatamente, seguindo para depois dele.continue— pula o resto do corpo e vai direto para a próxima iteração (nofor, executa a atualização antes de testar de novo).
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue; // pula os pares: nada abaixo executa nesta iteração
}
if (i > 7) {
break; // ao chegar em 9, abandona o laço
}
printf("%d ", i); // imprime: 1 3 5 7
}
Use com parcimônia
break e continue são úteis, mas em excesso tornam o laço difícil de seguir. Muitas
vezes uma condição bem escrita (ou um if dentro do corpo) deixa a intenção mais
clara do que um break no meio.
Curiosidade 💡 — laços intencionalmente infinitos
Às vezes queremos um laço "sem fim" que só termina por um break interno (por exemplo,
o laço principal de um jogo ou de um menu). Dois idiomas comuns:
while (1) { ... if (sair) break; ... } // 1 é sempre verdadeiro
for (;;) { ... if (sair) break; ... } // for com os três campos vazios
break é a única saída.
10. Laços aninhados¶
Um laço pode conter outro laço. Para cada iteração do laço externo, o laço interno roda por completo. São indispensáveis para trabalhar com estruturas bidimensionais (tabelas hoje; matrizes na Semana 09).
#include <stdio.h>
int main(void) {
for (int i = 1; i <= 3; i++) { // externo: cada tabuada
printf("Tabuada do %d:\n", i);
for (int j = 1; j <= 10; j++) { // interno: as 10 linhas
printf(" %d x %d = %d\n", i, j, i * j);
}
printf("\n");
}
return 0;
}
Se o externo roda 3 vezes e o interno 10, o printf de dentro executa 3 × 10 = 30
vezes. Note que usamos variáveis de controle diferentes (i e j) — confundi-las é
um erro comum.
Desenhando com laços aninhados
Um clássico para fixar a ideia — imprimir um triângulo:
for (int lin = 1; lin <= 4; lin++) {
for (int col = 1; col <= lin; col++) { // o interno depende do externo!
printf("*");
}
printf("\n");
}
// Saída:
// *
// **
// ***
// ****
* de cada linha depende de lin — o laço interno vai até lin.
11. Erros comuns desta semana (resumão)¶
Checklist de armadilhas
- Laço infinito por esquecer a atualização da variável de controle.
- Erro de contagem por um (off-by-one): usar
<=onde era<, ou começar em 1 onde era 0. Confira sempre o primeiro e o último valor. - Esquecer o
;no fim dodo-while. - Colocar
;logo apósfor (...)ouwhile (...)(corpo vazio — como noif). - Inicializar o acumulador com o valor errado (produto começando em 0).
- Deixar a sentinela entrar na conta (soma/contagem).
- Reutilizar a mesma variável em laços aninhados (
ino lugar dej).
👥 Quarta — Encontro¶
Chegue tendo estudado e executado os exemplos. No encontro vamos:
- Traduzir um problema em laço: identificar inicialização, condição e atualização.
- Depurar, ao vivo, um laço infinito e um erro off-by-one.
- Construir juntos um programa com laço aninhado.
Problema-guia — estatísticas com sentinela: ler vários números até o usuário digitar
-1; ao final, informar quantos foram lidos, a soma, a média e o maior
deles.
#include <stdio.h>
int main(void) {
int valor, soma = 0, quantidade = 0, maior = 0;
printf("Digite numeros (-1 para encerrar):\n");
scanf("%d", &valor);
while (valor != -1) {
soma += valor;
quantidade++;
if (quantidade == 1 || valor > maior) { // o 1º valor sempre vira o maior inicial
maior = valor;
}
scanf("%d", &valor);
}
if (quantidade > 0) {
printf("Qtd=%d Soma=%d Media=%.2f Maior=%d\n",
quantidade, soma, (double) soma / quantidade, maior);
} else {
printf("Nenhum numero informado.\n");
}
return 0;
}
Para pensar antes: por que a condição do "maior" precisa do quantidade == 1? O que
aconteceria se inicializássemos maior = 0 e todos os números fossem negativos?
✍️ Sexta — Estudo dirigido¶
Exercícios guiados (Beecrowd)¶
Resolva, em C, na ordem sugerida:
| Nº | Problema | O que exercita |
|---|---|---|
| 1059 | Números Pares | for simples |
| 1060 | Números Positivos | contador dentro do laço |
| 1064 | Positivos e Média | contador + acumulador |
| 1065 | Impares entre dois números | classificação em laço |
| 1070 | Seis Ímpares | for com passo |
| 1072 | Calculando e Somando | laço com condicional dentro |
| 1073 | Quadrado dos Pares | expressão dentro do laço |
| 1078 | Tabuada | laço de contagem |
| 1080 | Maior e Posição | encontrar máximo com laço |
| 1116 | Dividindo Valores | validação (do-while) |
| 1132 | Multiples of 13 | acumulador condicional |
Desafios para escrever do zero¶
- Múltiplos: imprimir todos os números de 1 a 100 que sejam múltiplos de 3 ou 5.
- Fatorial: ler
ne calcularn!com um laço (cuidado: acumulador começa em 1). - É primo? ler um número e testar se é primo (verifique divisores de 2 até
n-1). - Contagem regressiva: ler
ne imprimir denaté 1, e depois "Fim!". - Soma dos dígitos: ler um inteiro e somar seus dígitos (dica:
% 10pega o último dígito,/ 10remove-o; repita com umwhile). - Tabela de conversão: imprimir uma tabela de Celsius (0 a 100, de 10 em 10) para
Fahrenheit, bem alinhada com
%de largura. - Pirâmide: com laços aninhados, imprimir um triângulo de números:
Para investigar (curiosidade prática)¶
- Escreva um
for (int i = 0; i < 5; i++)e outrofor (int i = 0; i <= 5; i++). Quantas vezes cada um executa? Relacione com o erro off-by-one. - Rode um laço
while (1)que imprime e não tembreak. Interrompa comCtrl + Ce reflita sobre o que aconteceu.
✅ Checklist de autoavaliação¶
- Reconheço os três ingredientes de um laço e sei por que um laço fica infinito.
- Escrevo
while,do-whileefore escolho o adequado a cada situação. - Uso contadores e acumuladores, inicializando-os corretamente.
- Implemento o padrão sentinela sem contar o valor de parada.
- Sei usar
breakecontinueconscientemente. - Consigo escrever e rastrear um laço aninhado, prevendo quantas vezes o corpo roda.
- Evito o erro off-by-one conferindo o primeiro e o último valor.
🔗 Referências e para se aprofundar¶
- Material 2026.1 — Aula 03: Estruturas de Repetição.
- BACKES, André. Linguagem C: completa e descomplicada (estruturas de repetição).
- KERNIGHAN, B.; RITCHIE, D. The C Programming Language, cap. 3.
- MIZRAHI, Victorine V. Treinamento em Linguagem C (comandos de repetição).
- Referência: cppreference — for · while.
- Prática: Beecrowd.
Antes de seguir para a Semana 04
Você já tem os três pilares da lógica: sequência, decisão e repetição. Na próxima semana vamos aprender a organizar tudo isso em funções — blocos reutilizáveis que deixam programas grandes gerenciáveis. É o que fecha a Unidade 1.