A maior rede de estudos do Brasil

Grátis
146 pág.
Programando com PASCAL - Jaime Evaristo

Pré-visualização | Página 22 de 50

o menor divisor próprio de vários inteiros}
program DivisorProprio;
var Num, Divisor : integer;
Raiz : real;
begin
Num := 1;
while Num <> 0 do
begin
write('Digite um numero (0 para encerrar): ');
readln(Num);
Raiz := SqrT(Num);
Divisor := 2;
while (Num mod Divisor <> 0) and (Divisor <= Raiz) do
Divisor := Divisor + 1;
if Divisor <= Raiz
then
writeln(Divisor, ' eh divisor proprio de ', Num);
else
 writeln(Num, ' eh primo');
end;
end.
4.4 O comando repeat until
Como dissemos na seção anterior, o número de execuções da seqüência de comandos associada a um 
comando while pode ser zero. Há situações em que é importante se garantir a execução de uma seqüência de 
comandos pelo menos uma vez. Uma delas é a verificação da consistência dos dados de entrada. Esta ação 
consiste em se dotar o programa de recursos para recusar dados incompatíveis com a entrada do programa, 
só "recebendo" dados que satisfaçam às especificações (lógicas ou estabelecidas) dos dados de entrada. Por 
exemplo, se a entrada é um número correspondente a um mês do ano, o programa não deve aceitar uma 
entrada que seja menor do que 1 nem maior do que 12. Uma solução para esta questão utilizando o comando 
while poderia ser a seguinte:
. . .
var Mes : integer;
begin
writeln('Digite o mes: ');
readln(Mes);
while (Mes < 1) or (Mes > 12)
begin
writeln(Chr(7), 'Digitacao errada! Digite de novo');
writeln('Digite o mes: ');
readln(Mes);
end;
 . . . 
Observe que, como a verificação da condição de repetição é feita no "início" do comando, há a 
necessidade de um comando readln antes da estrutura e outra dentro dela (para lembrar, a função Chr(x) 
retorna o caractere de código ASCII x; o caractere de código ASCII igual a 7 é um caractere não imprimível 
e a execução de writeln(Chr(7)) faz com que o sistema emita um sinal sonoro, um beep).
O comando repeat until define uma estrutura de repetição que garante que uma seqüência de comandos 
seja executada pelo menos uma vez. Sua sintaxe é
repeat
seqüência de comandos;
until Expressão lógica;
e sua semântica é a seguinte: a seqüência de comandos é executada e a Expressão é avaliada; se o valor da 
Expressão for false, a seqüência de comandos é novamente executada e tudo se repete; do contrário, o 
comando que segue a estrutura é executado. Isto significa que a execução da seqüência de comandos será 
repetida até que a Expressão lógica seja verdadeira.
A consistência da entrada de um dado relativo a um mês utilizando um comando repeat poderia ser a 
seguinte.
. . .
var Mes : integer;
begin
repeat
writeln('Digite o mes: ');
readln(Mes);
if (Mes < 1) or (Mes > 12)
 then
writeln(Chr(7), 'Digitacao errada! Digite de novo');
 until (Mes >= 1) and (Mes <= 12);
. . .
Pode-se também utilizar o comando repeat until para execuções sucessivas de um programa. Neste caso, 
é comum se fazer uma pergunta do tipo Deseja continuar (S/N)? após cada execução. Naturalmente, é 
necessária uma variável do tipo char que receba a resposta do usuário e que será utilizada para controlar a 
estrutura de repetição. Teríamos algo como:
var Resp : char;
. . .
repeat
{seqüência de comandos do programa propriamente dito}
writeln('Deseja continuar (S/N)?');
readln(Resp);
until UpCase(Resp) = 'N';
Vale lembrar que a função UpCase retorna o argumento no formato maiúsculo. Esta função foi ativada 
aqui para que o usuário não se preocupe em digitar como resposta letras maiúsculas. Qualquer letra que for 
digitada, a função a torna maiúscula e o sistema a compara com S (maiúsculo).
4.5 Exemplos Parte VI
1. Consideremos um programa para determinar a soma dos n primeiros números pares positivos, n dado. 
Por exemplo, se for fornecido para n o valor 6, o programa deve retornar 42, pois
2 + 4 + 6 + 8 + 10 + 12 = 42. Naturalmente, o sistema pode gerar os números pares que se pretende somar, 
através do comando Par := 2 e da repetição do comando Par = Par + 2. Naturalmente, também, para que o 
sistema gere o próximo par, o anterior já deverá ter sido somado. Isto pode ser feito através do comando 
Soma = 0 e da repetição do comando Soma = Soma + Par. Temos então o seguinte programa.
{Programa que soma os n primeiros números pares, n dado}
program SomaPares;
var Soma, Par, n, i : integer;
begin
write('Digite o valor de n: ');
readln(n);
Par := 2;
Soma := 0;
for i := 1 to n do
begin
Soma := Soma + Par;
 Par := Par + 2;
end;
writeln('Soma dos ', n, ' primeiros números pares: ', Soma);
end.
Observe que os comandos Par = 2 e Soma = 0 atribuem um valor inicial às variáveis para que estes 
valores iniciais possam ser utilizados nas primeiras execuções dos comandos Soma = Soma + Impar e Impar 
= Impar + 2. Como já dissemos, chamamos um comando que atribui valor inicial a uma variável para que 
este valor possa ser utilizado na primeira execução de um comando que terá sua execução repetida 
denominada inicialização da variável.
Uma outra observação interessante é que, como existe uma fórmula que dá o i-ésimo número par
(ai = 2i), o programa acima poderia ser escrito de uma forma mais elegante, prescindindo, inclusive, da 
variável Par.
{Programa que soma os n primeiros números pares positivos, n dado}
program SomaPares;
var Soma, n, i : integer;
begin
writeln('Digite o valor de n: ');
readln(n);
Soma := 0;
for i := 1 to n do
Soma := Soma + 2*i;
writeln('Soma dos ', n, ' primeiros números pares: ', Soma);
end.
Optamos por apresentar a primeira versão pelo fato de que nem sempre a fórmula para gerar os termos da 
seqüência que se pretende somar é tão simples ou é muito conhecida. Por exemplo, o exercício número 2 da 
seção 4.6 pede para somar os quadrados dos n primeiros números naturais e, neste caso, embora a fórmula 
exista, ela não é tão conhecida.
2. Um dos exemplos da seção anterior apresentava um programa que determinava, se existisse, um 
divisor próprio de um inteiro dado. Imaginemos agora que queiramos um programa que apresente a lista de 
todos os divisores próprios de um inteiro n dado. Neste caso, o programa pode percorrer todos os inteiros 
desde um até a metade de n verificando se cada um deles é um seu divisor. Temos então o seguinte 
programa.
{Programa que exibe os divisores próprios de um inteiro dado}
program Divisores;
var n, i : integer;
 Primo : boolean;
begin
Primo := true;
write('Digite o numero: ');
readln(n);
for i := 2 to (n div 2) do
if n mod i = 0
 then
 begin
writeln(i);
Primo := false;
end;
if Primo
then
 writeln(n, ' eh primo');
end.
Vale observar que, ao contrário do que foi dito na seção 2.9, os valores de saída deste programa não 
estão sendo armazenados. O que acontece é que ainda não temos condições de armazenar uma quantidade 
indefinida de elementos. Este problema será resolvido no capítulo 6. Vale observar também que a variável 
Primo é utilizada para detectar entradas correspondentes a números primos. Ela é inicializada com o valor 
true e seu conteúdo é modificado para false quando um divisor é encontrado.
3. Na seção 1.7 discutimos um algoritmo que determinava o quociente e o resto da divisão entre dois 
inteiros positivos dados. Embora os compiladores da linguagem Pascal possuam os operadores mod e div que 
calculam o resto e o quociente de uma divisão inteira entre dois inteiros positivos, vamos apresentar a 
implementação do algoritmo referido. Esta apresentação se justifica pelo fato de que este é um excelente 
exemplo de lógica de programação e também pelo fato de que o leitor pode um dia utilizar um sistema que 
não possua tais operadores.
{Programa que determina o quociente e o resto da divisao entre dois inteiros positivos}
var Divid, Divis, Quoc, Rest : integer;
begin
writeln('Digite o dividendo e