ALGORITMOS E ESTRUTURAS DE DADOS I
259 pág.

ALGORITMOS E ESTRUTURAS DE DADOS I


DisciplinaAlgoritmos e Estrutura de Dados I708 materiais7.919 seguidores
Pré-visualização50 páginas
existir uma maneira melhor para se programar a func¸a\u2dco. Felizmente
existe: basta passar um para\u2c6metro, isto e´, basta informar a` func¸a\u2dco que os ca´lculos
sera\u2dco feitos para um dado nu´mero inteiro, na\u2dco importando o nome da varia´vel que
conte´m o valor sobre o qual sera´ feito o ca´lculo da paridade. Isto e´ conseguido
mudando-se o proto´tipo da func¸a\u2dco para o seguinte:
function eh par (n: integer) : boolean;
Em outras palavras, a func¸a\u2dco vai receber um nu´mero inteiro, no caso denominado
n (mas poderia ser a, b ou qualquer outro identificador, o importante e´ que seja do
tipo integer. O tipo do retorno e´ o mesmo, isto e´, boolean.
Com isto, conseguimos escrever o programa (ja´ com a func¸a\u2dco recebendo para\u2c6metros
por valor), da maneira como esta´ apresentado na figura 9.3.
Esta maneira de passar para\u2c6metros caracteriza uma passagem por valor, tambe´m
conhecida como passagem de para\u2c6metros por co´pia. O que ocorre e´ que o identificador
n da func¸a\u2dco recebe uma co´pia do valor da varia´vel a do programa principal. As
alterac¸o\u2dces em n sa\u2dco feitas nesta co´pia, mantendo-se intactos os dados da varia´vel a no
programa principal. Isto ocorre pois esta co´pia e´ feita em a´rea separada de memo´ria,
denominada pilha.
9.2. NOC¸O\u2dcES FUNDAMENTAIS 113
program imprime pares ;
var a: integer ;
(\u2217 funcao que calcula se a variavel global a eh par \u2217)
function eh par (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.3: Programa que imprime os nu´meros da entrada que sa\u2dco pares.
9.2.6 Para\u2c6metros por refere\u2c6ncia
Para passar para\u2c6metros por refere\u2c6ncia, o proto´tipo da func¸a\u2dco difere ligeiramente da-
quele exibido acima. A chamada e´ assim:
function eh par (var n: integer) : boolean;
A diferenc¸a 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;