A maior rede de estudos do Brasil

Grátis
146 pág.
livro programando com pascal - jaime evaristo

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

é incrementado de uma unidade e tudo se repete até que fahrenheit atinja o valor 81. 
Desta forma, a execução deste programa gera a seguinte tabela
Tabela de conversão graus fahrenheit/graus Celsius
fahrenheit Celsius
20 -6.67
21 -5.11
22 -5.56
23 -5.00
.
.
.
.
.
.
79 26,11
80 26,67
Vale observar que, ao contrário de outras linguagens (C, por exemplo), a variável de controle tem que ser 
necessariamente de um tipo ordenado. Se quiséssemos que a tabela também fornecesse temperaturas em 
graus Fahrenheit fracionárias (meio em meio grau, por exemplo), teríamos de considerar uma outra variável 
do tipo integer para controlar o comando for:
program TabelaDeConversaoFarenheitCelsius;
uses Crt;
var i : integer;
Celsius, Farenheit : real;
begin
ClrScr;
writeln('Tabela de conversao graus fahrenheit/graus Celsius');
writeln('-------------------------------------------------');
writeln(' Farenheit | Celsius');
writeln('-------------------------------------------------');
Farenheit := 20
for i := 1 to 121 do
begin
Celsius := 5.0*(Farenheit - 32)/9;
writeln(' ', Farenheit,' ', Celsius:0:2);
Farenheit := Farenheit + 0.5
end;
end.
Certamente com a estrutura de repetição a seguir, o programa anterior ficasse um pouco mais simples.
4.3 O comando while
Para introduzir uma nova estrutura de repetição e cotejá-la com o comando for, considere um programa 
para encontrar um divisor próprio de um inteiro dado (um divisor próprio de um inteiro n é um divisor de n 
menor que n e diferente de 1. Esta questão é importante na verificação da primalidade de um inteiro: um 
número que não tem divisores próprios é primo, conforme [Evaristo, J. 2002]). Com a utilização do comando 
for, teríamos a seguinte solução para esta questão.
{Programa que determina um divisor próprio de um inteiro}
program DivisorProprio;
var Num, i, Divisor : integer;
begin
write('Digite um numero: ');
readln(Num);
Divisor := 0;
for i := 2 to Num - 1 do
if Num mod = 0
then
Divisor := i;
if Divisor <> 0
then
writeln(Divisor, ' eh divisor proprio de ', Num);
else
writeln(Num, ' eh primo');
end.
Um problema com este programa é que ele retorna sempre, se existir, o maior divisor próprio. Isto 
significa que, se a entrada for um número par, a estrutura de repetição não é interrompida quando o divisor 2 
é encontrado, o que, evidentemente, vai prejudicar a performance do programa. Este problema pode ser 
resolvido em alguns compiladores Pascal que permitem que uma variável de controle de um comando for 
tenha o seu conteúdo alterado dentro do próprio comando. Com isto, o programa acima ficaria da seguinte 
forma.
{Programa que determina um divisor próprio de um inteiro}
program DivisorProprio;
var Num, i, Divisor : integer;
begin
write('Digite um numero: ');
readln(Num);
Divisor := 0;
for i := 2 to Num - 1 do
if Num mod = 0
then
begin
Divisor := i;
i := Num – 1;
 end;
if Divisor <> 0
then
writeln(Divisor, ' eh divisor proprio de ', Num);
else
writeln(Num, ' eh primo');
end.
Nesta versão, quando o primeiro divisor próprio é encontrado, o comando
i := Num – 1 e o seguinte incremento da variável i faz com que a execução do comando for seja 
interrompida. A prática de alterar o conteúdo da variável de controle não será aqui incentivada pelo fato de 
que outras linguagens não a permitem. Na verdade, a questão central é que o comando for deve ser utilizado 
quando o número de repetições de execução de uma seqüência de comandos é conhecido a priori. Quando 
isto não acontece (que é o caso do exemplo anterior: não se sabe a priori se e quando um divisor próprio vai 
ser encontrado), deve-se usar o comando while, que possui a seguinte sintaxe:
while Expressão lógica do
seqüência de comandos
Quando da sua execução, a Expressão lógica é avaliada. Se for verdadeira, a seqüência de comandos é 
executada e o processamento retorna ao próprio comando while. Se for falsa, a seqüência não é executada e o 
processamento se transfere para o comando seguinte. 
Naturalmente, pode ocorrer que a seqüência não seja executada nenhuma vez, isto acontecendo se a 
Expressão lógica for falsa quando da “primeira” execução do comando. Por outro lado, se a tal expressão 
lógica permanecer verdadeira, a seqüência de comandos terá sua execução infinitamente repetida o que 
implicará a não-execução da tarefa. Se isto acontece, dizemos que o programa está em looping e é necessária 
a digitação da combinação das teclas <Ctrl> + <Break> para interromper a sua execução.
Com o comando while as questões levantadas acima sobre o programa para determinar um divisor 
próprio de um inteiro dado são resolvidas e temos o seguinte programa:
{Programa que determina o menor divisor próprio de um inteiro}
program DivisorProprio;
var Num, Divisor : integer;
begin
write('Digite um numero: ');
readln(Num);
Divisor := 2;
while Num mod Divisor <> 0 do
Divisor := Divisor + 1;
if Divisor < Num
then
writeln(Divisor, ' eh divisor proprio de ', Num);
else
writeln(Num, ' e primo');
end.
Como todo inteiro é divisor de si mesmo, a estrutura while sempre será interrompida. Se foi interrompida 
com Divisor < Num, é porque um divisor próprio foi encontrado; se foi interrompida com Divisor = Num, 
então Num é primo.
Evidentemente esta versão é bem mais eficiente do que aquela que utilizava o comando for e o 
interessante é que ela ainda pode ser melhorada, pois a matemática prova que, se um inteiro não possui um 
divisor próprio menor do que sua raiz quadrada, então ele é primo (ver [Evaristo, J 2002]). Levando em 
conta este fato, teríamos o seguinte programa:
{Programa que determina o menor divisor próprio de um inteiro}
program DivisorProprio;
var Num, Divisor : integer;
begin
write('Digite um numero: ');
readln(Num);
Divisor := 2;
while (Num mod Divisor <> 0) and (Divisor <= SqrT(Num)) do
Divisor := Divisor + 1;
if Divisor <= SqrT(Num)
then
writeln(Divisor, ' e divisor proprio de ', Num);
else
writeln(Num, ' e primo');
end.
Na procura de se aprender a escrever programas mais eficientes, observe que a função SqrT foi executada 
duas vezes para o mesmo valor. Num caso como este, é mais interessante considerar uma variável para 
armazenar o valor da função e utilizar o conteúdo da variável nos outros comandos. Desta forma o programa 
anterior poderia ser assim escrito:
{Programa que determina o menor divisor próprio de um inteiro}
program DivisorProprio;
var Num, Divisor : integer;
Raiz : real;
begin
write('Digite um numero: ');
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, ' e divisor proprio de ', Num);
else
writeln(Num, ' e primo');
end. 
Aproveitando o ensejo, vale observar que o comando Divisor := 2; dos programas acima atribuiu um 
valor inicial à variável Divisor. Este valor era modificado quando não era um divisor de Num. Um comando 
de atribuição de um valor inicial a uma variável é chamado inicialização da variável.
Uma outra aplicação importante do comando while diz respeito a execuções sucessivas de um programa. 
O leitor deve ter observado que os programas anteriores são executados apenas para uma entrada. Se 
quisermos a sua execução para outra entrada, precisamos executar o programa de novo. 
Pode-se repetir a execução de um programa quantas vezes se queira, colocando-o numa estrutura definida 
por um comando while, controlada pelo valor de algum dado de entrada. Neste caso, o valor que encerra a 
execução pode ser informado dentro da mensagem que indica a necessidade da digitação da entrada. O 
programa anterior poderia ser então escrito da seguinte forma.
{Programa que determina