apostila
259 pág.

apostila


DisciplinaAlgoritmos e Estrutura de Dados I674 materiais7.931 seguidores
Pré-visualização50 páginas
sinta´tica e´ caracterizada pela palavra var antes do nome do identifica-
dor do para\u2c6metro.2 Pode parecer sutil, mas com uma sema\u2c6ntica totalmente diferente
daquela da passagem de para\u2c6metros por valor.
O que antes era uma co´pia, agora e´ uma refere\u2c6ncia ao enderec¸o da varia´vel do
programa principal. Isto e´, no momento da ativac¸a\u2dco da func¸a\u2dco, o identificador n
da func¸a\u2dco e´ associado com o mesmo enderec¸o da varia´vel a no programa principal.
Consequentemente, qualquer alterac¸a\u2dco associada a n na func¸a\u2dco provocara´ alterac¸a\u2dco
do valor da varia´vel a no programa principal.
Vejamos na figura 9.4 como fica a modificac¸a\u2dco no programa em estudo do ponto de
vista meramente sinta´tico. Deixamos o ponto de vista sema\u2c6ntico para ser explicado
no pro´ximo exemplo.
2Com todo o respeito ao Niklaus Wirth, usar a palavra var para este fim na\u2dco foi uma boa escolha,
pois para um principiante e´ fa´cil confundir com uma passagem de para\u2c6metros por refere\u2c6ncia com
uma declarac¸a\u2dco de uma varia´vel, o que na\u2dco e´ definitivamente o caso aqui.
114 CAPI´TULO 9. FUNC¸O\u2dcES E PROCEDIMENTOS
program imprime pares ;
var a: integer ;
(\u2217 funcao que calcula se a variavel global a eh par \u2217)
function eh par (var n: integer) : boolean;
begin
if n mod 2 = 0 then
eh par:= true
else
eh par:= false ;
end;
begin (\u2217 programa principal \u2217)
read (a) ;
while a <> 0 do
begin
if eh par (a) then
writeln (a) ;
read (a) ;
end;
end.
Figura 9.4: Versa\u2dco com para\u2c6metros por refere\u2c6ncia.
9.2.7 Procedimentos
Um procedimento difere de uma func¸a\u2dco basicamente pois na\u2dco tem um valor de retorno
associado. Isto faz com que ele se comporte como um comando extra da linguagem ao
passo que a func¸a\u2dco tem um comportamento mais parecido com o de uma expressa\u2dco
aritme´tica ou booleana. Um proto´tipo para um procedimento e´ definido enta\u2dco com
base em apenas duas informac¸o\u2dces:
1. o identificador do procedimento (nome);
2. a lista de para\u2c6metros (que podem ser por valor ou refere\u2c6ncia).
Para explicar corretamente a noc¸a\u2dco de procedimentos, e tambe´m de varia´veis lo-
cais, e´ importante mudar de exemplo. Vamos considerar o problema de se ler dois
nu´meros reais x e y do teclado, fazer a troca dos conteu´dos e depois imprimir.
Vamos considerar o seguinte proto´tipo para um procedimento que recebe os dois
valores x e y e tem a finalidade de realizar a troca dos conteu´dos destas varia´veis:
procedure troca (var a, b: real) ;
Observe que, assim como no caso da func¸a\u2dco, na\u2dco importa muito o nome dos identi-
ficadores dos para\u2c6metros, apenas importa que eles definam conteu´dos do tipo REAL.
Podemos enta\u2dco tentar escrever um programa que leia dois valores e os imprima
trocados, conforme ilustrado na figura 9.53:
3Um exerc´\u131cio interessante e´ passar os para\u2c6metros por valor e compreender o efeito disso.
9.2. NOC¸O\u2dcES FUNDAMENTAIS 115
program imprimetrocado ;
var x,y,temp: real ; (\u2217 variaveis globais \u2217)
(\u2217 procedimento que troca os conteudos da variaveis \u2217)
procedure troca (var a, b: real) ;
begin
temp:= a;
a:= b;
b:= temp;
end;
begin (\u2217 programa principal \u2217)
read (x,y) ;
troca (x,y) ;
writeln (x,y) ;
end.
Figura 9.5: Versa\u2dco com para\u2c6metros por refere\u2c6ncia.
Este programa usa uma varia´vel global (temp) para auxiliar a troca, o que na\u2dco
faz muito sentido. Os subprogramas devem funcionar independentemente de varia´veis
globais.
9.2.8 Varia´veis locais
Varia´veis locais sa\u2dco declaradas nos subprogramas e te\u2c6m escopo local, isto e´, elas so´ sa\u2dco
conhecidas durante a execuc¸a\u2dco do subprograma. Consequentemente na\u2dco interferem
no programa principal. O programa modificado da figura 9.6 faz uso da varia´vel local
temp e torna o co´digo mais robusto.
program imprimetrocado ;
var x,y: real ; (\u2217 variaveis globais \u2217)
(\u2217 procedimento que troca os conteudos da variaveis \u2217)
procedure troca (var a, b: real) ;
var temp: real ; (\u2217 variavel local , temporaria para uso exclusivo neste procedimento \u2217)
begin
temp:= a;
a:= b;
b:= temp;
end;
begin (\u2217 programa principal \u2217)
read (x,y) ;
troca (x,y) ;
writeln (x,y) ;
end.
Figura 9.6: Versa\u2dco com uma varia´vel local.
116 CAPI´TULO 9. FUNC¸O\u2dcES E PROCEDIMENTOS
9.3 Alguns exemplos
Nesta sec¸a\u2dco vamos implementar dois problemas simples para exercitar.
9.3.1 Calculando d´\u131gito verificador
Vamos fazer um programa que recebe um nu´mero de N d´\u131gitos, sendo o u´ltimo deles
o \u201cd´\u131gito verificador\u201d do nu´mero formado pelos N \u2212 1 primeiros. Devemos calcular se
o d´\u131gito verificador fornecido pelo usua´rio esta´ correto segundo o esquema de ca´lculo
seguinte: cada d´\u131gito do nu´mero, comec¸ando da direita para a esquerda (menos sig-
nificativo para o mais significativo) e´ multiplicado, na ordem, por 1, depois 2, depois
1, depois 2 e assim sucessivamente. O nu´mero de entrada do exemplo e´ 261533-4.
+---+---+---+---+---+---+ +---+
| 2 | 6 | 1 | 5 | 3 | 3 | - | 4 |
+---+---+---+---+---+---+ +---+
| | | | | |
x2 x1 x2 x1 x2 x1
| | | | | |
=4 =6 =2 =5 =6 =3
+---+---+---+---+---+-> = 26
Como 26 tem dois d´\u131gitos, vamos repetir o processo acima ate´ gerarmos um nu´mero
de um u´nico d´\u131gito. Assim:
+---+---+
| 2 | 6 |
+---+---+
| |
x2 x1
| |
=4 =6
+---+ = 10
Como 10 ainda tem dois d´\u131gitos, o algoritmo roda ainda mais uma vez:
+---+---+
| 1 | 0 |
+---+---+
| |
x2 x1
| |
=2 =0
+---+ = 2
Assim, o d´\u131gito verificador calculado (2) difere daquele fornecido (4) e o programa
deveria acusar o erro. O programa da figura 9.7 ilustra uma poss´\u131vel soluc¸a\u2dco.
9.3. ALGUNS EXEMPLOS 117
program digitoverificador ;
var numero, n: longint ;
dv, dv correto : integer ;
procedure le (var n: longint) ;
begin
{$i\u2212}
repeat
read (n) ;
until ioresult = 0;
{$i+}
end;
procedure separa numero e dv (n: longint ; var num: longint ; var dv: integer) ;
begin
num:= n div 10;
dv:= n mod 10;
end;
function calcula dv correto (n: longint) : integer ;
var soma, mult, ultimo : integer ;
begin
repeat
soma:= 0;
mult:= 1;
while n <> 0 do
begin
ultimo:= n mod 10;
n:= n div 10;
soma:= soma + mult \u2217 ultimo ;
i f mult = 1 then
mult:= 2
else
mult:= 1;
end;
n:= soma;
until (n > 0) and (n<= 9) ;
calcula dv correto:= soma;
end;
begin (\u2217 programa principal \u2217)
le (numero) ;
separa numero e dv (numero, n, dv) ;
dv correto:= calcula dv correto (n) ;
i f dv correto <> dv then
writeln (\u2019digito verificador invalido.\u2019)
end.
Figura 9.7: Calculando d´\u131gito verificador.
118 CAPI´TULO 9. FUNC¸O\u2dcES E PROCEDIMENTOS
O importante para se observar neste co´digo e´ a clareza do algoritmo no programa
principal. O leitor pode acompanhar este trecho e perceber claramente as diversas
etapas em uma linguagem de bastante alto n´\u131vel: leitura do nu´mero, separac¸a\u2dco deste
em duas partes, uma contendo os primeiros d´\u131gitos a outra contendo o dv de entrada.
Em seguida o ca´lculo do d´\u131gito verificador correto e finalmente a comparac¸a\u2dco dos
dados calculados com o de entrada, gerando a mensagem final.
No programa principal pode-se ignorar completamente como sa\u2dco feitas todas as
operac¸o\u2dces nas func¸o\u2dces e procedumentos: na\u2dco importa como os dados sa\u2dco lidos, nem
como os d´\u131gitos sa\u2dco separados, e muito menos como e´ feito o ca´lculo do d´\u131gito verifi-
cador correto. No programa principal o importante e´ o algoritmo em alto n´\u131vel.
E´ claro que em algum momento sera´ necessa´rio escrever co´digo para cada uma das
func¸o\u2dces e procedimentos, mas quando isto for feito o programador estara´ resolvendo
um subproblema de cada vez, o que facilita muito a construc¸a\u2dco do co´digo para o
problema global.
Por exemplo, a leitura poderia ser feita em uma interface gra´fica ou textual. Foi es-
colhida nesta versa\u2dco uma interface textual, mas que permite testes de consiste\u2c6ncia dos
dados de entrada. Isto, feito separadamente, mante´m