13 Repetições com do while
Este capítulo contempla a estrutura e aspectos lógicos do do while
, cuja função é executar comandos repetitivamente.
13.1 A estrutura de repetição do while
O do while
é uma estrutura de repetição condicional e, assim, depende de uma dada condição para determinar se haverá ou não outra repetição. Em oposição ao while
(Capítulo 11) e ao for
(Capítulo 12), o teste de continuidade é feito depois da execução do comando.
Nessa estrutura de repetição, o primeiro passo é a execução de comando que, como nas demais estruturas, pode ser um comando simples ou um bloco de comandos. Terminada a execução, a condição_de_continuidade é avaliada, seguindo para nova repetição se for verdadeira ou encerrando do while
se não for.
Assim, esta estrutura executa comando pelo menos uma vez.
Para exemplificar, o trecho de código seguinte ilustra uma leitura de um valor real garantindo que esteja no intervalo de 0 a 10 (inclusive).
/*
Leitura de valor com garantia de estar no intervalo [0, 10], com releitura
se necessário
Requer: uma sequência de valores terminada por um no intervalo [0, 10]
Assegura: apresentação do último valores
*/
#include <stdio.h>
int main(void) {
double valor;
do {
char entrada[160];
("Digite um valor: ");
printf(entrada, sizeof entrada, stdin);
fgets(entrada, "%lf", &valor);
sscanf} while (valor < 0 || valor > 10);
("\nValor aceito: %g.\n", valor);
printf
return 0;
}
12.2
Digite um valor: -3.05
Digite um valor: 7.4
Digite um valor:
Valor aceito: 7.4.
A lógica da leitura é direta: faz a leitura e, caso não esteja no intervalo especificado, faz a leitura novamente. Neste caso, a primeira leitura é necessária e seu valor sempre é relevante.
Um detalhe relevante é o escopo das declaraçoes de variáveis: como entrada
é usada apenas localmente, é declarada dentro do bloco de comandos do do while
; valor
, por sua vez, tem que ser declarada fora (antes) do bloco, caso contrário não existiria para ser escrita depois da repetição.
Em um laço do while
, as variáveis declaradas dentro do bloco de comandos ficam tão restritas ao próprio bloco que não podem nem ser acessadas na condição da repetição.
do {
bool eh_valido; // declaração interna
...
} while (eh_valido); // `eh_valido` não existe aqui...
13.2 Exemplos
Nesta seção há alguns exemplos de programas que utilizam a estrutura de repetição do while
.
13.2.1 Leitura de senha
Este exemplo é de um programa que solicita uma senha para autorizar ou não a execução. A senha é hardcoded (i.e., fixa no código e nada versátil) e há um limite de três tentativas.
/*
Processamento somente mediante senha
Requer: uma sequência de tentativas de senha terminada com a senha correta
ou com comprimento máximo de três tentativas
Assegura: apresentação de mensagem autorizando ou negando acesso conforme a
a senha esteja ou não correta
*/
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
int main(void) {
bool validou_senha = false;
int numero_tentativas = 0;
do {
++;
numero_tentativas("Digite a senha: ");
printfchar senha[160];
(senha, sizeof senha, stdin);
fgets
= strcmp(senha, "12345678\n") == 0; // é igual?
validou_senha } while (!validou_senha && numero_tentativas < 3);
if (validou_senha)
("\nAcesso autorizado.\n");
printfelse
("\nAcesso negado.\n*** Este problema será reportado.\n");
printf
return 0;
}
senha
Digite a senha: senha123
Digite a senha: 123456
Digite a senha:
Acesso negado. *** Este problema será reportado.
Neste código há o uso da função strcmp
, declarada no arquivo de cabeçalho string.h
. Ela retorna zero se as duas cadeias de caracteres passadas como parâmetro forem iguais1. Uma observação interessante é que senha
é declarada dentro do bloco do do while
, uma vez que ela não é necessária fora dele; o mesmo comentário não é válido para validou_senha
.
13.2.2 Pense em um número de 1 a 15.000!
O programa deste exemplo se propõe a adivinhar um número pensado pelo usuário em no máximo 13 tentativas.
/*
Pense em um número de 1 até 15.000 para eu adivinhar qual é!
Requer: respostas do usuário dizendo se o valor é maior (+) ou menor (-)
que o número pensado
Assegura: a apresentação do número pensado pelo usuário em até 14 tentativas
*/
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
int main(void) {
("Pense em um número de 1 a 15000 e responda...\n");
printf(8); // 8s para pensar!
sleep
int inicio_intervalo = 1;
int fim_intervalo = 15000;
int numero_tentativas = 0;
int tentativa;
bool acertei = false;
do {
++;
numero_tentativas= (inicio_intervalo + fim_intervalo) / 2;
tentativa
("É o %d?\n", tentativa);
printf("Responda + se o número for maior, - se for menor "
printf"ou = se eu acertei: ");
char resposta[160];
(resposta, sizeof resposta, stdin);
fgetsswitch (resposta[0]) {
case '+':
= tentativa + 1; // tentarei número maior
inicio_intervalo break;
case '-':
= tentativa - 1; // tentarei número menor
fim_intervalo break;
case '=':
= true; // UFA!
acertei break;
default:
("Não entendi a resposta... tente de novo.\n");
printf--; // essa tentativa não conta!
numero_tentativas}
if (!acertei) {
if (numero_tentativas == 13)
("Minha ÚLTIMA CHANCE!!!\n");
printfelse if (numero_tentativas > 10)
("Só tenho mais %d chances.. :-(\n",
printf14 - numero_tentativas);
(0.7); // pausa leve de dramaticidade
sleep}
} while (!acertei && fim_intervalo >= inicio_intervalo);
if (acertei)
("\n\nBeleza! Acertei em %d tentativas!\n", numero_tentativas);
printfelse
("\n\nHummmm! Algo de errado não está certo aqui...\n"
printf"Suas respostas foram corretas?\n");
return 0;
}
Pense em um número de 1 a 15000 e responda...
É o 7500?+
Responda + se o número for maior, - se for menor ou = se eu acertei:
É o 11250?+
Responda + se o número for maior, - se for menor ou = se eu acertei:
É o 13125?+
Responda + se o número for maior, - se for menor ou = se eu acertei:
É o 14063?-
Responda + se o número for maior, - se for menor ou = se eu acertei:
É o 13594?-
Responda + se o número for maior, - se for menor ou = se eu acertei:
É o 13359?+
Responda + se o número for maior, - se for menor ou = se eu acertei:
É o 13476?=
Responda + se o número for maior, - se for menor ou = se eu acertei:
Beleza! Acertei em 7 tentativas!
Manipulações de cadeias de caracteres são tratadas em detalhes no Capítulo 16.↩︎