Você está na página 1de 17

Notas de Aula de o de Computadores Algoritmos e Programac a

F L AVIO K EIDI M IYAZAWA com a colaborac a o de T OMASZ KOWALTOWSKI

Instituto de Computac a o - UNICAMP

Vers ao 2000.1

Estas notas de aula n ao devem ser usadas como u nica fonte de estudo. O aluno deve ler outros livros dispon veis na literatura. Nenhuma parte destas notas pode ser reproduzida, qualquer que seja a forma ou o meio, sem a permiss ao dos autores. Os autores concedem a permiss ao expl cita para a utilizac a o e reproduc a o deste material no contexto do ensino de disciplinas regulares dos cursos de graduac a o sob a responsabilidade do Instituto de Computac a o da UNICAMP.

c Copyright 2000

Instituto de Computac a o UNICAMP Caixa Postal 6176 13083970 CampinasSP fkm,tomasz @ic.unicamp.br

ii

5 Desenvolvendo Programas
o por Etapas 5.1 Programac a
Quando um programa comec a a car maior ou mais complicado, e comum se fazer primeiro um esboc o, contendo operac o es em alto n vel, mesmo que sejam complexas. Nos passos seguintes este esboc o e detalhado em operac o es mais espec cas at e que se chegue na codicac a o do programa na linguagem de programac a o. Exemplo 5.1 Fac a um programa que l e tr es n umeros , e e verica se estes n umeros formam os lados de um tri angulo. Em caso armativo, o programa verica se o tri angulo formado e atero (tr es lados iguais), is oceles equil (dois lados iguais) ou escaleno (tr es lados diferentes). Vamos desenvolver este programa por etapas. Podemos considerar os seguintes passos principais: Passo 1: Leia , e . Passo 2: Se  n ao formam um tri angulo ent ao Passo 3: Passo 5: Passo 6: Passo 7: Passo 8: Passo 9: Escreva: Os valores lidos n ao formam um tri angulo.


Passo 4: Sen ao se

formam um tri angulo equil atero ent ao




Escreva: Os valores lidos formam um tri angulo equil atero. Sen ao se formam um tri angulo is oceles ent ao Escreva: Os valores lidos formam um tri angulo is oceles. Sen ao Escreva: Os valores lidos formam um tri angulo escaleno.

Esta estrutura descreve uma estrat egia para resolver o problema, sem se preocupar com cada um dos testes mais complicados (condic o ao destacadas). A traduc a ao destacados para a linguagem Pascal e es que est o dos comandos n praticamente direta. Assim, vamos nos preocupar com cada um dos testes destacados. 1. No passo 2, temos de vericar quando tr es n umeros n ao formam os lados de um tri angulo. Isto pode ser feito vericando se um dos valores e a maior que a soma dos outros dois valores. Assim, podemos trocar a condic o do passo 2 por:  ! ou "#$%! ou %#&' 2. No passo 4 devemos testar se os valores , e formam um tri angulo equil atero. Isto e es verdadeiro se os tr valores s ao iguais e pode ser feito usando duas relac o es de igualdade. )(01 e "2(3 3. No passo 6 devemos testar se os valores , e formam um tri angulo is oceles. Neste caso devemos vericar se qualquer dois dos tr es valores s ao iguais. 4(5' ou 6(3 ou "7(3 Substituindo estas condic o es no algoritmo acima e traduzindo para a Linguagem Pascal, temos:

39

program triangulo; var a,b,c: real; begin write(Entre com o primeiro lado: ); readln(a); write(Entre com o segundo lado: ); readln(b); write(Entre com o terceiro lado: ); readln(c); if 89 !A@BC"#$%!A@BD#$E&'8 then n ao existe tri angulo writeln(Os n umeros n ao formam um tri angulo.) else if 4(5'AFHGPIQ4(3 then e angulo equil atero tri writeln(O tri angulo e atero) equil else if 6(01R@HBD6(5'R@HBD"2(3 then e angulo is oceles tri writeln(O tri angulo e oceles) is angulo escaleno else e tri writeln(O tri angulo e escaleno) end. Exemplo 5.2 Programa para ler 3 n umeros decrescente de valor.
SUT

, SAV e SAW e imprimir

XSUT8SAVY8SAW'

de maneira a carem em ordem n ao

Um primeiro esboc o, que apresenta uma estrat egia para se resolver o problema, e dada a seguir: 1. Ler os tr es n umeros nas vari aveis Sa`b8SRcd8SRe . 2. Trocar os valores das vari aveis Sa`b8SRcd8SRe , de forma que SRe cont em um maior valor entre Sa`b8SRcd8SRe . Neste em um valor correto. momento, SRe cont 3. Trocar os valores das vari aveis Sa`b8SRc , de forma que SRc cont em um maior valor entre Sa`b8SRc . 4. Imprimir XSa`b8SRcd8SRef .

Em um segundo passo, podemos descrever a estrat egia acima de forma mais detalhada, omitindo alguns passos ainda desconhecidos. program ordena3; var Sa`b8SRcd8SRe : real; begin write(Entre com o primeiro n umero: ); readln XSa` ; write(Entre com o segundo n umero: ); readln XSRcf ; write(Entre com o terceiro n umero: ); readln XSRef ; if XSRe)g&Sa` then troca valores de SRe e Sa` if XSRe)g&SRcf then troca valores de SRe e SRc Neste ponto, SRe cont em um maior valor dos tr es valores lidos. if XSRc)g&Sa` then troca valores de SRc e Sa` Neste ponto, SRc cont em um segundo maior valor dos tr es valores lidos. Ap os acertar os valores em SRe e SRc , observe que Sa` cont em um menor valor dos tr es lidos. writeln XSa`b8SRcd8SRef ; end. 40

Agora considere o problema de se trocar os valores contidos em apenas duas vari aveis. Digamos que voc e queira ao e vel passar o valor de h para i diretamente, j a que isto faria trocar os valores das vari aveis h e i . N poss com que perd essemos o valor original de i . Da mesma forma, tamb em n ao e vel passar o valor de i para h poss diretamente, sem perda do valor original de h . Isto nos induz a usar uma outra vari avel auxiliar, AUX, para primeiro guardar o valor de i , em seguida passar o valor de h para i , e depois passar o valor de AUX para h . Isto nos d aa seguinte seq ue o pqsrut t tvpqwr ncia de operac es: i ; i h ; h ; Substituindo este processo de troca dos valores em vari aveis no pseudo programa acima, obtemos o seguinte programa nal: program ordena3; var n1,n2,n3, AUX: real; begin write(Entre com o primeiro n umero: ); readln(n1); write(Entre com o segundo n umero: ); readln(n2); write(Entre com o terceiro n umero: ); readln(n3); if (n3 g n1) then begin AUX: ( n3; n3:( n1; n1: ( AUX; end; if (n3 g n2) then begin AUX: ( n3; n3:( n2; n2: ( AUX; end; if (n2 g n1) then begin AUX: ( n2; n2:( n1; n1: ( AUX; end; writeln(n1,n2,n3); end. Exerc cio 5.1 Descreva um programa usando a mesma estrat egia do exemplo 5.2 para ordenar quatro n umeros nas vari aveis Sa` , SRc , SRe e Swx . Exerc cio 5.2 A estrat egia do exemplo 5.2 foi a de colocar o maior dos valores lidos na vari avel correta (acertar o etodo para acertar as vari aveis restantes (vari aveis Sa` e SRc ). Fac a um valor em SRe ) e em seguida aplicar o mesmo m programa para ordenar tr es n umeros como no exemplo 5.2, mas usando a estrat egia de colocar o menor dos valores lidos na vari avel correta (vari avel Sa` ) e reaplicar o mesmo m etodo para as demais vari aveis (vari aveis SRc e SRe ).

o de programas 5.2 Simulac a


Uma simulac a o de um programa nada mais e que simular o comportamento de um programa em um computador. As simulac o es que faremos tem por objetivo vericar se o programa est a realmente correto ou encontrar o erro de um programa incorreto. aconselh E avel que se fac a sempre uma simulac a o do programa antes de implement a-lo no computador. Isto permitir a que o programador possa tratar poss veis erros no momento em que estiver projetando o programa e saber como consert a-lo mais facilmente uma vez que as id eias e estrat egias usadas no desenvolvimento do programa estar ao mais frescas em sua mem oria. Muitos compiladores que integram ambientes de editorac a o possibilitam a execuc a o de um programa passo a passo e a observac a o de todo o processamento dos dados existentes na mem oria. Com isso, as simulac o es podem ser feitas diretamente neste software integrado. Outros compiladores podem inserir informac o es dentro do c odigo execut avel do programa contendo as informac o es necess arias para se fazer uma execuc a o passo a passo no programa fonte. Para fazer uma simulac a o em papel, precisamos ter o programa e uma mem oria em papel. Nesta simulac a o voc e estar a simulando o computador acompanhando o programa e processando os dados que est ao na mem oria de papel. Isto e , voc e far a o trabalho da CPU. A seguir iremos descrever como fazer esta simulac a o. 41

Primeiramente, descreva uma tabela, colocando na primeira linha os nomes de todas as vari aveis declaradas no programa, como apresentado abaixo. Caso seja uma func a o ou procedimento (veja sec a o 7) n ao esquec a de colocar tamb em os par ametros declarados nestas rotinas. Vari avel-1 Vari avel-2
y'y'y

Vari avel-K

Par ametro-1

y'y'y

Par ametro-M

Em seguida coloque os valores iniciais destas vari aveis e par ametros. Caso n ao tenha sido atribu do nenhum valor a elas, coloque a palavra lixo (j a que e um valor que voc e desconhece). No caso de par ametros, coloque os valores que foram passados como par ametros (alguns podem ser lixo tamb em). Qualquer operac a o que utilize o valor lixo tamb em resulta em lixo. Vari avel-1 lixo Vari avel-2 lixo Vari avel-3 lixo Par ametro-1 valor-param1 Par ametro-2 lixo

Vamos fazer a simulac a o de um programa para ler uma seq ue ncia de n umeros inteiros n ao negativos terminada com um n umero inteiro negativo. O programa deve imprimir a soma e quantidade dos n umeros n ao negativos.

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.

program Sequencia; var x,soma,n : integer; begin write(Entre com um n umero: ); readln(x); soma : 0; n : 0; while (x 0) do begin soma : soma x; n : n 1; write(Entre com um n umero: ); readln(x); end; writeln(Soma=,soma, Quantidade=,n); end.

42

Marcaremos o comando que acabou de ser executado com uma marca (inicialmente marcado no begin do bloco de comandos do programa principal). Vamos supor que a entrada e a seq ue ncia: 1,2,3,-1.
1. program Sequencia; 2. var x,soma,n : integer; begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; 7. n : 0; 8. while (x P 0) do begin 9. soma : soma x; 10. n : n 1; 11. write(Entre com um n umero: ); 12. readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end. 1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); readln(x); 6. soma : 0; 7. n : 0; 8. while (x P 0) do begin 9. soma : soma x; 10. n : n 1; 11. write(Entre com um n umero: ); 12. readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end. 1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; n : 0; 8. while (x P 0) do begin 9. soma : soma x; 10. n : n 1; 11. write(Entre com um n umero: ); 12. readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end. 1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; 7. n : 0; while (x P 0) do begin 9. soma : soma x; 10. n : n 1; 11. write(Entre com um n umero: ); 12. readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end.

x lixo

Soma lixo

n lixo In cio da Simulac a o Seq ue ncia a testar: 1,2,3,-1

x lixo 1

Soma lixo

n lixo Execuc a o dos passos 4 e 5. Leitura do valor 1.

x lixo 1

Soma lixo 0

n lixo 0 Execuc a o dos passos 6 e 7. Inicializac a o de Soma e n.

x lixo 1

Soma lixo 0

n lixo 0

Teste da condic a o do while. Elemento lido e ? `E$ ? Sim. Entrar no loop.

43

1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; 7. n : 0; 8. while (x P 0) do begin 9. soma : soma x; n : n 1; 11. write(Entre com um n umero: ); 12. readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end. 1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; 7. n : 0; 8. while (x P 0) do begin 9. soma : soma x; 10. n : n 1; 11. write( Entre com um n umero: ); readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end. 1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; 7. n : 0; while (x P 0) do begin 9. soma : soma x; 10. n : n 1; 11. write(Entre com um n umero: ); 12. readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end. 1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; 7. n : 0; 8. while (x P 0) do begin 9. soma : soma x; n : n 1; 11. write(Entre com um n umero: ); 12. readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end. 1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; 7. n : 0; 8. while (x P 0) do begin 9. soma : soma x; 10. n : n 1; 11. write(Entre com um n umero: ); readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end.

x lixo 1

Soma lixo 0 1

n lixo 0 1

Execuc a o dos passos 9 e 10. Acumular valor em Soma. Incrementar S .

x lixo 1 2

Soma lixo 0 1

n lixo 0 1

Execuc a o dos passos 11 e 12. Leitura do valor 2.

x lixo 1 2

Soma lixo 0 1

n lixo 0 1

Teste da condic a o do while. Elemento lido e ? c6$ ? Sim. Entrar no loop.

x lixo 1 2

Soma lixo 0 1 3

n lixo 0 1 2

Execuc a o dos passos 9 e 10. Acumular valor em Soma. Incrementar S .

x lixo 1 2 3

Soma lixo 0 1 3

n lixo 0 1 2

Execuc a o dos passos 11 e 12. Leitura do valor 3.

44

1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; 7. n : 0; while (x P 0) do begin 9. soma : soma x; 10. n : n 1; 11. write(Entre com um n umero: ); 12. readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end. 1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; 7. n : 0; 8. while (x P 0) do begin 9. soma : soma x; n : n 1; 11. write(Entre com um n umero: ); 12. readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end. 1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; 7. n : 0; 8. while (x P 0) do begin 9. soma : soma x; 10. n : n 1; 11. write(Entre com um n umero: ); readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end. 1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; 7. n : 0; while (x P 0) do begin 9. soma : soma x; 10. n : n 1; 11. write(Entre com um n umero: ); 12. readln(x); 13. end; 14. writeln(Soma=,soma, Quantidade=,n); 15. end. 1. program Sequencia; 2. var x,soma,n : integer; 3. begin 4. write(Entre com um n umero: ); 5. readln(x); 6. soma : 0; 7. n : 0; 8. while (x P 0) do begin 9. soma : soma x; 10. n : n 1; 11. write(Entre com um n umero: ); 12. readln(x); 13. end; writeln(Soma=,soma, Quantidade=,n); 15. end.

x lixo 1 2 3

Soma lixo 0 1 3

n lixo 0 1 2

Teste da condic a o do while. Elemento lido e ? e6$ ? Sim. Entrar no loop.

x lixo 1 2 3

Soma lixo 0 1 3 6

n lixo 0 1 2 3

Execuc a o dos passos 9 e 10. Acumular valor em Soma. Incrementar S .

x lixo 1 2 3 -1

Soma lixo 0 1 3 6

n lixo 0 1 2 3

Execuc a o dos passos 11 e 12. Leitura do valor -1.

x lixo 1 2 3 -1

Soma lixo 0 1 3 6

n lixo 0 1 2 3

Teste da condic a o do while. Elemento lido e ? `%$ ? N ao. Ir para o pr oximo comando depois do loop.

x lixo 1 2 3 -1

Soma lixo 0 1 3 6

n lixo 0 1 2 3

Impress ao de Soma e S . Soma = 6 n =3

45

5.3 Alinhamento de Comandos

if (Condic a o) then begin b4b


d

Nesta sec a o apresentamos algumas formas de alinhamen b4b to que visam a melhor visualizac a o dos comandos (ou d declarac o es) que est ao sob atuac a o de outros. Estas per- end else begin b4b mitem que programas quem melhor apresentados e mais d f aceis de se entender. A id eia e fazer com que os coman. . . dos que est ao sob atuac a o de outros estejam alinhados e b4bA d deslocados alguns espac os a direita. end; A seguir apresentamos algumas exemplos de alinhamento para alguns comandos. O leitor n ao necessariamente precisa seguir esta regra, mas e importante que se use - Comando for alguma regra razo avel de alinhamento dos comandos. for i:=(Express ao) to (Express ao) do uY u Obs.: As barras verticais s ao apenas para visualizar o ali zSA d nhamento dos comandos. es: const, type e var. - Declarac o const
eCf

. . .

for i:=(Express ao) to (Express ao) do begin b4b


d

. . .

b4b d

h(`'`bd (5edgh`1xi`jlkdd

end;

type

nm'opf {

m'rtslu S q w r}|ub~uYm

(5vGpwxdyHxdBzd (3'wBbvGRyUid

- Comando while while a o) do (Condic


uY zSA u d

var

%%vXGpwxzyxzBzd 8%BxdFHd

- Bloco de Comandos: begin


b4bpff b4bpfb d d

while (Condic a o) do begin b4b


d

. . .

b4b d

end;

. . .

b4bpf d

end; - Comando if-then, if-then-else. if (Condic a o) then


u zSA u

- Comando repeat repeat


b4b d

. . .

b4b d

until (Condic a o);

if (Condic a o) then begin b4bpfb


d

. . .

b4bpf d

end;

46

Alinhamento de comandos encaixados Quando um comando e colocado internamente a outro comando, o comando interno e todos sobre sua atuac a o s ao deslocados adicionalmente ao alinhamento do comando externo. Exemplo 5.3 No exemplo a seguir apresentamos o esboc o de um programa com alguns comandos encaixados em outros e o alinhamento em cada um deles. program Esboc oAlinhamento; var
%%vXGpwxzyxzBzd 8%BxdFHd

begin
xGPIg xGRId BYxzxzFw b 4bpf d . . . 4bpf2 b d xGRId xGRId xGRId xGRId vX

if (Condic a o) then begin


b4bpf d

for i:=(Express ao) to (Express ao) do begin


b4bpf d

. . .

b4bpfU d

(Condic a o) then begin


b4bpf d

for i:=(Express ao) to (Express ao) do begin


b4b8 d

. . .

b4b8U d

while ao) do begin (Express if (Condic a o) then begin


b4b8#P d

. . .

b4b8#w d

end else begin . . .

b4b8U

b4b8U

A d

xGRId b4bd

. . .

b4bd d

until (Condic a o) d

47

5.4 Desenvolvimento de Algoritmos Ecientes


Em geral teremos in umeros algoritmos para se resolver o mesmo problema. Alguns deles podem ser r apidos, enquanto outros podem exigir mais processamento e conseq ue ntemente podem resultar em programas lentos ou at e mesmo invi aveis de serem executados. Outros algoritmos podem ser r apidos mas podem consumir muita mem oria, deixando o programa igualmente invi avel. Ao desenvolver um algoritmo, precisamos considerar os prop ositos do algoritmo juntamente com os recursos computacionais usados por ele. Dois dos principais recursos computacionais s ao o tempo de processamento e a mem oria. Outra considerac a o importante e o grau de facilidade de desenvolvimento e manutenc a o do programa. Programas escritos de maneira simples s ao em geral mais f aceis de se dar manutenc a o do que aqueles que usam estruturas complexas e c odigos otimizados. No exemplo seguinte consideramos algumas vers oes de algoritmos para o problema de se vericar se um n umero e primo ou n ao. Exemplo 5.4 Fac a um programa para vericar se um n umero positivo, lido pelo programa, e ao. Obs.: primo ou n Um n umero positivo maior que 1 e vel somente por ele mesmo e pela unidade. primo se e divis Program Primo1; var i,n : integer; EhPrimo : Boolean; begin writeln(Programa para verificar se um n umero positivo e primo ou n ao.); write(Entre com o n umero a testar: ); readln(n); EhPrimo: ( True; for i: ( 2 to n 1 do if (n mod i ( 0) then EhPrimo : ( false; if (EhPrimo) and (n  1) then writeln(O n umero ,n, e primo. ) else writeln(O n umero ,n, n ao e primo. ) end. f O programa acima e acil ver que ele est a correto, observando apenas a denic a bem simples e compacto. E o de n umero primo, n a ao ser divis vel por nenhum n umero entre cd'g'g'g8S `Y , e do comando de repetic o que percorre vel por um deles. Al em disso, este programa usa pouca mem oria, uma vez que estes n umeros testando se S e divis usamos um pequeno n umero de vari umero grande, a quantidade de interac o aveis. Por outro lado, se S e um n es e no pior casos igual a S c . Um outro extremo e a armazenados todos os n umeros represent aveis de nosso interesse (por exem quando temos j plo: os n umeros que podem ser armazenados em um tipo inteiro de 2 bytes), dizendo se cada um e ao. Note primo ou n que isto j a exigiu um grande pr e-processamento para todos os n umeros, mas uma vez feito isso, todas as consultas f poder ao ser feitas em tempo constante e portanto extremamente r apido. E acil ver que este tipo de soluc a o pode ser invi avel devido a grande mem oria usada para armazenar todos estes n umeros. Uma soluc a astica seria o menos dr armazenar todos os primos represent aveis (em vez de todos os n umeros). Mas mesmo com esta reduc a o a quantidade de primos existentes e em disso agora n ao podemos mais fazer o teste em tempo constante ( e poss vel fazer grande, al em tempo proporcional a }l  , onde e a quantidade de primos). Outra estrat egia interessante e testar primeiro para um subconjunto xo de primos (quantidade constante). Por ao e ario exemplo, vamos testar inicialmente se S e vel por c (i.e., S e primo, caso contr divis par); em caso positivo, S n testamos apenas para os elementos mpares dos n umeros em ed'g'g'gY8S `Y . Isto j a nos d a um algoritmo que faz, no pior caso, em torno da metade do processamento do primeiro algoritmo. Uma estrat egia interessante e sticas do problema para se tentar otimizar o estudarmos mais sobre as caracter programa. Note que se um n umero S n ao e ao deve ser poss vel escrever S como S()yb . Sem perda de primo, ent generalidade, considere . Para vericar se S n ao e ao se encontramos primo, basta achar um dos divisores. Ent ao e ario testar para os outros n umeros maiores que . Al em disso, podemos usar o fato de ser , n mais necess 48

limitado por S . Este fato e bem menor que S , o que reduz importante uma vez que para valores grandes de S , S e bastante a quantidade de testes feito pelo programa. O seguinte programa apresenta a implementac a eia. o desta id Program Primo2; var i,n : integer; Max : real; EhPrimo : Boolean; begin writeln(Programa para verificar se um n umero positivo e primo ou n ao.); write(Entre com o n umero a testar: ); readln(n); if (n ( 2) then EhPrimo : ( true else if (n mod 2 ( 0) or (n g( 1) then EhPrimo: ( False else begin EhPrimo: ( True; i: ( 3; Max : ( sqrt(n); while (i g( Max) and (n mod i gE 0) do i : ( i  2; if (i g( Max) and (n mod i ( 0) then EhPrimo : ( false; end; if EhPrimo then writeln(O n umero ,n, e primo. ) else writeln(O n umero ,n, n ao e primo. ); end. o Note que se S(`'fe` (S e a primo), o primeiro programa faz 1029 interac es, no comando de repetic o, e o programa acima, que tamb em faz uso de uma quantidade constante de mem oria, faz apenas 15 interac o es. Exerc cio 5.3 Fac a um programa que verica se um n umero e em de pular primo, como no programa Primo2, mas al os m ultiplos de 2, tamb em pula os m ultiplos de 3.

5.5 Precis ao Num erica e Erros de Precis ao


A linguagem Pascal nos oferece o tipo real para trabalharmos com n umeros. Em geral este tipo e implementado internamente com uma quantidade xa de bytes, o que torna imposs vel a representac a o exata de todos os n umeros. Isto e razo avel uma vez que h a innitos n umeros reais, mesmo em intervalos pequenos como ` . Apesar disso, a maioria das implementac o es representa o n umero W internamente com uma boa quantidade de T casas decimais corretas. Por exemplo, se W for representado como elelelelelelelelelelelelefelele`j teremos o valor correto at e a `b casa decimal. Na maioria das aplicac o es este erro na precis ao pode ser desprez vel. Um dos principais problemas com erros de precis ao e o c alculo entre valores que j a cont em erros de precis ao, que podem gerar resultados com erros maiores. O seguinte programa mostra como o erro de precis ao em apenas uma conta faz com que tenhamos um resultado totalmente inesperado. program Terco; var i : integer; terco : real; begin terco : ( 1/3; for i: ( 1 to 30 do begin terco : ( 4 terco 1; writeln(Iterac ao: ,i:2,, Terco = ,terco:20:18); end; end. Se n ao houvesse erros de precis ao, a vari avel Terco comec aria com o valor
W T T

e em cada interac a o o valor de Terco

49

e atualizado como x%y ` . Se Terco tivesse o valor W , o novo valor de Terco seria x7y T e , em cada interac a o Terco recebe novamente o valor W . W

p18

que e igual a W . Isto

No entanto, a maioria dos programas execut aveis constru dos a partir deste programa fonte deve imprimir, na T u ltima interac a o, um valor que e totalmente diferente de W . Vamos analisar este programa com mais detalhes. Note que W n ao deve ser armazenado de forma exata, sendo armazenado correto at e certa casa decimal. Portanto, h a um pequeno erro de precis ao na primeira atribuic a o de Terco. T Vamos supor que o valor realmente atribu do seja igual a W , onde  e este pequeno erro de precis ao. A seguir, vamos computar os valores de Terco em cada interac a o: Interac a o In cio 1 Terco
( W T (3x%y ' ` ` T T

. . . 30

. . .

(3x%yp W T ( x W ' (3x%y T (3x%y W x y % T V x ( W ' (3x%y T V (3x%y W x T W x ( W ' T

)

` `

` y `

(3x%y

` y `

V8 (3x%y W x T W8 ( x W W8

Note que x e um n umero muito grande, e mesmo que seja bem pequeno, o valor x chega a ser maior que W , resultando em um valor negativo para Terco. A func a o XSP(xl e uma func a o exponencial e tem um crescimento T x a o sXSP( W e dominada pelo termo x . Assim, o valor extremamente r apido. A medida que S cresce a func sXSP rapidamente se torna negativo.

W8

50

A seguinte tabela apresenta a impress ao gerada pela execuc a o deste programa (o programa execut avel foi gerado em um computador Sun-Sparc 4 com o compilador gpc Gnu Pascal Compiler). Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: Interac a o: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, Terco = 0,33333333333333325931847 Terco = 0,33333333333333303727386 Terco = 0,33333333333333214909544 Terco = 0,33333333333332859638176 Terco = 0,33333333333331438552705 Terco = 0,33333333333325754210819 Terco = 0,33333333333303016843274 Terco = 0,33333333333212067373097 Terco = 0,33333333332848269492388 Terco = 0,33333333331393077969551 Terco = 0,33333333325572311878204 Terco = 0,33333333302289247512817 Terco = 0,33333333209156990051270 Terco = 0,33333332836627960205078 Terco = 0,33333331346511840820312 Terco = 0,33333325386047363281250 Terco = 0,33333301544189453125000 Terco = 0,33333206176757812500000 Terco = 0,33332824707031250000000 Terco = 0,33331298828125000000000 Terco = 0,33325195312500000000000 Terco = 0,33300781250000000000000 Terco = 0,33203125000000000000000 Terco = 0,32812500000000000000000 Terco = 0,31250000000000000000000 Terco = 0,25000000000000000000000 Terco = 0,00000000000000000000000 Terco = -1,00000000000000000000000 Terco = -5,00000000000000000000000 Terco = -21,00000000000000000000000

es: Observac o ltima interac a o ter amos algo como W x , 1. Caso a primeira atribuic a o de Terco seja algo como W  ,  , na u que igualmente daria um valor inesperado para Terco, mas desta vez positivo. 2. Note que o u nico lugar onde consideramos um erro de precis ao foi na primeira atribuic a o de Terco e todas as outras atribuic o es envolveram c alculos exatos.
T T W8

51

5.6 Tipos denidos pelo programador


Al em dos tipos j a denidos na linguagem Pascal, e poss vel se construir novos tipos associados a apenas um identicador. Assim, poderemos declarar tipos complicados e associar este tipo com um identicador. A denic a o destes novos tipos deve ser feita na a rea de declarac o es, usando a palavra reservada type seguida das denic o es de cada tipo. Cada tipo novo e denido como: IdenticadorDeTipo = especicac a o do tipo; Exemplo 5.5 Declare tipos chamados MeuInteiro, TipoNome e TipoNumero, onde MeuInteiro e igual ao tipo integer, TipoNome e igual ao tipo string[50] e TipoNumero e igual ao real. type MeuInteiro = integer; TipoNome = string[50]; TipoNumero = real; Exemplo 5.6 Os seguintes programas s ao equivalentes:

program ExemploTipos; type TipoNome ( string[50]; MeuInteiro ( integer; var Idade : MeuInteiro; Nome : TipoNome; begin write(Entre com seu nome: ); readln(Nome); write(Entre com sua idade: ); readln(Idade); writeln(Nome, tem ,idade, anos.); end.

program ExemploTipos; var Idade : integer; Nome : string[50]; begin write(Entre com seu nome: ); readln(Nome); write(Entre com sua idade: ); readln(Idade); writeln(Nome, tem ,idade, anos.); end.

Exemplo 5.7 Outros exemplos de declarac o aveis. es de tipos e vari program Exemplo; type TipoNome ( string[50]; TipoRG string[15]; ( TipoIdade ( integer; TipoSalario ( real; var NomePedro,NomePaulo : TipoNome; IdadePedro,IdadePaulo : TipoIdade; RgPedro,RgPaulo : TipoRG; SalarioPedro,SalarioPaulo : TipoSalario; Algumas vantagens e necessidades de se usar tipos:

Basta se lembrar do nome do tipo, sem precisarmos escrever toda a especicac a o de um novo objeto a ser declarado. Um exemplo disto e o caso do TipoRG usado no exemplo acima, a cada vez que formos declarar um RG, n ao precisaremos nos lembrar se um RG e declarado com 15 ou 16 ou mais caracteres; esta preocupac a o j a foi considerada no momento da especicac a o do tipo TipoRG.

52

As re-especicac o es de tipos cam mais f aceis. Usando string[15] em todos os lugares onde declaramos um RG e se quisermos mudar para string[20], devemos percorrer todo o programa procurando pelas declarac o es de RGs e fazendo as devidas modicac o es (note que isto n ao pode ser feito de qualquer forma, j a que nem todo lugar onde aparece string[15] e uma declarac a o de RG. Usando tipos, basta mudar apenas uma vez, i.e., na especicac a o de TipoRG. Al em disso h a tipos de objetos da linguagem Pascal que n ao admitem declarac o es usando mais que uma palavra. Alguns tipos de objetos deste caso s ao os par ametros e as func o es, que veremos na pr oxima sec a o.

53

Você também pode gostar