while e do-while
Esta aula aborda as estruturas de repetição while e do-while em C, destacando suas diferenças, condições de parada, loops infinitos e quando utilizar cada uma. Inclui exemplos práticos e exercícios para fixação.
Nesta aula, vamos explorar duas das estruturas de repetição mais fundamentais da linguagem C: while e do-while. Ambas permitem executar um bloco de código repetidamente enquanto uma condição for verdadeira, mas diferem no momento em que a condição é avaliada. Compreender essas diferenças é essencial para escrever loops corretos e eficientes.
O loop while é conhecido como uma estrutura de pré-teste, pois a condição é verificada antes da execução do bloco. Já o do-while é uma estrutura de pós-teste, garantindo que o bloco seja executado pelo menos uma vez. Vamos detalhar cada um, com exemplos práticos e boas práticas.
Diferenças
A principal diferença entre while e do-while está no momento da avaliação da condição. No while, a condição é testada antes de cada iteração; se for falsa desde o início, o bloco nunca é executado. No do-while, a condição é testada após a execução do bloco, garantindo que o bloco seja executado ao menos uma vez.
Exemplo: se você precisa ler dados do usuário até que ele forneça um valor válido, o do-while é mais adequado, pois você precisa ler pelo menos uma vez antes de verificar. Já para percorrer um array até encontrar um elemento, o while é natural, pois pode não haver iteração se o array estiver vazio.
// Exemplo: while vs do-while
#include <stdio.h>
int main() {
int x = 10;
// while: condição testada antes
while (x < 5) {
printf("while: x = %d\n", x);
x++;
}
printf("Após while, x = %d\n\n", x);
// do-while: condição testada depois
x = 10;
do {
printf("do-while: x = %d\n", x);
x++;
} while (x < 5);
printf("Após do-while, x = %d\n", x);
return 0;
}No exemplo acima, o bloco while nunca executa porque a condição é falsa desde o início. Já o do-while executa uma vez, mesmo que a condição seja falsa, imprimindo "do-while: x = 10".
Condições
As condições em while e do-while são expressões booleanas (em C, qualquer valor diferente de zero é verdadeiro). A condição pode ser simples ou composta, envolvendo operadores relacionais, lógicos ou até mesmo chamadas de função que retornam um valor inteiro.
É importante garantir que a condição se torne falsa em algum momento, caso contrário teremos um loop infinito. Além disso, a condição pode ser alterada dentro do bloco (por exemplo, incrementando uma variável de controle) ou depender de entrada externa.
// Exemplo: condição com entrada do usuário
#include <stdio.h>
int main() {
int numero;
printf("Digite números (0 para sair):\n");
do {
printf("Número: ");
scanf("%d", &numero);
printf("Você digitou %d\n", numero);
} while (numero != 0);
printf("Fim do programa.\n");
return 0;
}Neste exemplo, a condição depende do valor digitado pelo usuário. O loop continua enquanto o número for diferente de zero. O uso de do-while é apropriado porque precisamos ler pelo menos um número antes de verificar.
Loops infinitos
Loops infinitos ocorrem quando a condição nunca se torna falsa. Eles podem ser intencionais (por exemplo, em servidores que rodam para sempre) ou acidentais (como esquecer de atualizar a variável de controle). Em C, um loop infinito pode ser criado com while(1) ou for(;;). O do-while também pode ser infinito se a condição for sempre verdadeira.
Para evitar loops infinitos acidentais, sempre verifique se a condição será eventualmente falsa. Use ferramentas de debug ou adicione um contador de segurança em loops potencialmente longos.
// Loop infinito intencional (exemplo de menu)
#include <stdio.h>
int main() {
int opcao;
while (1) {
printf("Menu:\n");
printf("1. Opção 1\n");
printf("2. Opção 2\n");
printf("3. Sair\n");
printf("Escolha: ");
scanf("%d", &opcao);
if (opcao == 3) break;
printf("Você escolheu %d\n", opcao);
}
printf("Saindo...\n");
return 0;
}Neste exemplo, o loop é infinito por design (while(1)), mas a saída é controlada pelo comando break. Sem o break, o programa nunca terminaria.
Quando usar cada um
Use while quando você deseja que a condição seja verificada antes de cada execução, ou seja, quando pode ser que o bloco nunca seja executado. Exemplos: percorrer uma lista até encontrar um elemento, ler um arquivo até o fim, ou aguardar um evento.
Use do-while quando o bloco precisar ser executado pelo menos uma vez, independentemente da condição. É ideal para menus interativos, validação de entrada (como ler um número até que esteja em um intervalo), ou qualquer situação onde a primeira iteração é obrigatória.
Em geral, prefira while para a maioria dos casos, pois é mais claro que o bloco pode não executar. O do-while é menos comum, mas muito útil em cenários específicos.
// Comparação prática: validação de idade
#include <stdio.h>
int main() {
int idade;
// Com while: precisamos de uma inicialização extra
printf("Digite sua idade (0-150): ");
scanf("%d", &idade);
while (idade < 0 || idade > 150) {
printf("Idade inválida. Digite novamente: ");
scanf("%d", &idade);
}
// Com do-while: mais elegante
int idade2;
do {
printf("Digite sua idade (0-150): ");
scanf("%d", &idade2);
} while (idade2 < 0 || idade2 > 150);
printf("Idades válidas: %d e %d\n", idade, idade2);
return 0;
}O exemplo mostra que a validação com do-while é mais concisa, evitando a duplicação da leitura inicial.
Boas práticas e observações finais
Sempre inicialize as variáveis usadas na condição antes do loop. Evite modificar a condição dentro do bloco de maneiras inesperadas. Use nomes de variáveis descritivos para as condições. Considere usar break e continue com moderação, pois podem tornar o fluxo menos legível. Prefira loops com condição clara e evite loops infinitos acidentais.
Exercícios
- Escreva um programa em C que use um loop
whilepara imprimir os números de 1 a 10. - Escreva um programa que use um loop
do-whilepara ler números inteiros do usuário até que ele digite um número negativo. Ao final, exiba a soma dos números positivos digitados. - Crie um loop infinito intencional que exiba um menu com três opções (1, 2, 3) e use
breakpara sair quando o usuário digitar 3. - Explique a diferença entre
whileedo-whilecom suas próprias palavras e dê um exemplo ondedo-whileé mais adequado. - Escreva um programa que leia um número inteiro N e, usando um loop
while, calcule e exiba o fatorial de N (considere N >= 0).
#include <stdio.h>
int main() {
int i = 1;
while (i <= 10) {
printf("%d ", i);
i++;
}
printf("\n");
return 0;
}
#include <stdio.h>
int main() {
int num, soma = 0;
do {
printf("Digite um número (negativo para sair): ");
scanf("%d", &num);
if (num >= 0) soma += num;
} while (num >= 0);
printf("Soma dos positivos: %d\n", soma);
return 0;
}
#include <stdio.h>
int main() {
int opcao;
while (1) {
printf("Menu:\n");
printf("1. Opção 1\n");
printf("2. Opção 2\n");
printf("3. Sair\n");
printf("Escolha: ");
scanf("%d", &opcao);
if (opcao == 3) break;
printf("Você escolheu %d\n", opcao);
}
return 0;
}
while testa a condição antes de executar o bloco, podendo não executá-lo nenhuma vez. O do-while testa depois, garantindo pelo menos uma execução. Exemplo adequado: validação de entrada, onde precisamos ler ao menos um valor antes de verificar se é válido.
#include <stdio.h>
int main() {
int n, i = 1;
unsigned long long fat = 1;
printf("Digite um número inteiro não negativo: ");
scanf("%d", &n);
if (n < 0) {
printf("Número inválido.\n");
return 1;
}
while (i <= n) {
fat *= i;
i++;
}
printf("Fatorial de %d = %llu\n", n, fat);
return 0;
}