+ =
42 Algoritmos e Programao
- CONSIDERAES RELATIVAS AOS TIPOS DE DADOS DE SUBPROGRAMA:
- Como j foi explicado no curso, um subprograma tem acesso aos
dados declarados na zona de declaraes do subprograma so os
chamados dados locais, uma vez que esses dados no podem ser
acedidos fora do subprograma. Podemos ter constantes locais,
variveis locais e tipos locais.
- Um subprograma tambm tem acesso aos chamados dados
globais, que podem ser acedidos de qualquer parte do programa
principal e dos subprogramas. Este tipo de dados so os declarados
fora de qualquer subprograma, no sendo recomendvel o seu uso.
Um identificador declarado localmente num subprograma pode ter
o mesmo nome que um identificador global que foi declarado
externamente. No entanto, considerado uma m prtica de
programao (dentro do subprograma, a definio local ter maior
precedncia. Fora, o identificador local estar indefinido).
- Embora se possam utilizar dados globais num procedimento, deve-
se utilizar, sempre que possvel, dados locais. As vantagens so
evidentes:
. consegue-se uma melhor legibilidade do programa
. consegue-se uma maior facilidade na deteco e correco de
erros
. aumenta a portabilidade, uma vez que um mesmo
procedimento pode ser utilizado em aplicaes distintas com
dados globais prprios
. consegue-se uma gesto mais eficiente da memria, uma vez
que os dados locais apenas esto residentes na memria
durante a execuo do subprograma
Algoritmos e Programao 43
RECURSIVIDADE
Alguma coisa recursiva quando definida em termos dela prpria.
Um exemplo de recursividade (visual) so as imagens repetidas que
um determinado objecto gera quando colocado entre dois espelhos.
Em Programao, a recursividade um mecanismo til e poderoso
que permite que um subprograma se chame a si prprio, ou seja, um
subprograma diz-se recursivo se ele contm nas suas instrues, uma
chamada a ele prprio.
A ideia bsica de um algoritmo recursivo consiste em diminuir
sucessivamente o problema num problema menor ou mais simples,
at que o tamanho ou a simplicidade do problema reduzido permita
resolv-lo de forma directa, sem recorrer a ele mesmo.
- Quando isso ocorre, diz-se que o algoritmo atingiu uma condio
de paragem, a qual deve estar presente em pelo menos um local
dentro do algoritmo. Sem esta condio o algoritmo no parar de
se chamar a si mesmo, at estoirar a capacidade da pilha de
execuo.
Qualquer algoritmo recursivo tem soluo no recursiva (iterativa) que
executa a mesma tarefa, o contrrio j no verdade.
Exemplo: clculo do factorial de N.
Por definio matemtica, o factorial
de um nmero N representado por
N! (n factorial) e calculado da
forma apresentada ao lado:
Aqui fica a verso no recursiva do subprograma que permite calcular
o factorial de um nmero n.
>
=
=
0 N se 1)! - N.(N
0 N se 1
! N
44 Algoritmos e Programao
SUB FACTORIAL(IN n:INTEIRO):INTEIRO
fac,i:INTEIRO;
INICIO
fac1;
PARA in AT 1 PASSO -1 FAZER
fac fac * i;
FIMPARA
RETORNAR fac;
FIMSUB
E Aqui fica a verso recursiva que permite resolver o mesmo
problema:
SUB FACTORIAL(IN n:INTEIRO):INTEIRO
INICIO
SE n=0 ENTO
RETORNAR 1;
SENO
RETORNAR n*FACTORIAL(n-1);
FIMSE
FIMSUB
Explicao: Pela definio do subprograma anterior, o clculo do
factorial de 4 seria feito da seguinte forma:
4! = 4*3! = 4*(3*2!) = 4*(3*(2*1!)) = 4*(3*(2*(1*0!))) = 4*3*2*1
de notar que o subprograma chamado recursivamente com um
argumento decrescente at chegar ao patamar em que o clculo do
factorial trivial (0!, cujo valor 1). Este caso simples (condio de
paragem do subprograma), faz com que o subprograma no entre em
ciclo infinito e faa estoirar a pilha de execuo do computador.
A recursividade um recurso muito til em determinadas situaes,
permitindo criar algoritmos mais simples e elegantes que os seus
equivalentes no recursivos (ou tambm chamados de iterativos).
Alm disso, muitas vezes evidente a natureza recursiva do problema
a resolver, como , o caso do factorial anteriormente referido.
No entanto, a recursividade tambm tem algumas desvantagens:
>
=
=
0 N se 1)! - N.(N
0 N se 1
! N
Algoritmos e Programao 45
- Algoritmos recursivos consomem mais recursos (memria) do
computador, logo tendem a apresentar um desempenho inferior aos
equivalentes iterativos;
- A recursividade no de traagem fcil (depurao: testar o
algoritmo linha a linha), especialmente quando for grande a
profundidade de recurso (nmero mximo de chamadas
simultneas).
Exemplo 2: Desenvolver um subprograma que receba como
argumento um valor inteiro positivo e que para esse nmero calcule e
devolva o nmero de algarismos que o constituem. Desenvolva uma
verso recursiva e uma verso no recursiva para a resoluo deste
problema.
Verso iterativa:
SUB QUANTOSALGARISMOS(IN n:INTEIRO):INTEIRO
c:INTEIRO;
INICIO
c0;
ENQUANTO n<>0 FAZER
n n DIV 10;
c c + 1;
FIMENQUANTO
RETORNAR c;
FIMSUB
Verso Recursiva:
SUB QUANTOSALGARISMOS(IN n:INTEIRO):INTEIRO
INICIO
SE n=0 ENTO
RETORNAR 0;
SENO
RETORNAR 1 + QUANTOSALGARISMOS(n DIV 10)
FIMSE
FIMSUB
46 Algoritmos e Programao
Exemplo 3: A sequncia [1, 1, 2, 3, 5, 8, 13, 21, ...] conhecida como
sucesso ou srie de Fibonacci. Tem diversas aplicaes tericas e
prticas, na medida em que alguns padres na natureza parecem
segui-la.
O termo de ordem N desta
srie pode ser calculado
atravs da frmula:
Desenvolva verses recursivas e no recursivas de subprogramas que
permitam calcular o termo de ordem n da srie de fibonacci (sendo n
um valor inteiro fornecido ao subprograma atravs dos seus
argumentos).
verso recursiva:
SUB FIB(IN n:INTEIRO):INTEIRO
INICIO
SE n<=2 ENTO
RETORNAR 1; // retorna 1
SENO
RETORNAR FIB(n-2) + FIB(n-1);
FIMSE
FIMSUB;
verso no recursiva
SUB FIB(IN n:INTEIRO):INTEIRO
i,F1,F2,F:INTEIRO
INICIO
SE n<=2 ENTO
RETORNAR 1; // retornar 1
FIMSE
F2 1;
F1 1;
PARA i 1 AT n-1 PASSO 1 FAZER
F F2 + F1;
F2 F1;
F1 F;
FIMPARA
RETORNAR F;
FIMSUB
2 n se
2 n se
1 n se
) 1 ( ) 2 (
1
1
) (
>
=
=
+
=
n fib n fib
n fib
Algoritmos e Programao 47
48 Algoritmos e Programao
DADOS DE TIPO ESTRUTURADO
- AT AO MOMENTO LIDMOS APENAS COM DADOS DE TIPO ELEMENTAR:
os dados de tipo predefinido:
INTEIROS (integer/int)
REAIS (real/float)
CARACTERES (char/char)
LGICOS (boolean/..)
Um dado do tipo simples, ou elementar, representa um nico
elemento, que pode ser um caracter, um nmero inteiro, um real,
um valor lgico, ou um valor de um tipo definido pelo utilizador.
- NESTE CAPTULO VAMOS DEBRUARMO-NOS SOBRE OUTRA CLASSE DE
DADOS: OS DADOS DE TIPO ESTRUTURADO:
Os dados de tipo estruturado tm a particularidade de um nico
identificador poder representar mltiplos elementos.
Os vrios elementos de uma varivel do tipo estruturado podem
ser manipulados individualmente ou colectivamente.
Vectores e Matrizes (arrays)
- O ARRAY UM DADO DO TIPO ESTRUTURADO COM A PARTICULARIDADE
DE TODOS OS SEUS ELEMENTOS SEREM DO MESMO TIPO.
Por vezes h necessidade de representar um conjunto de elementos
atravs de um nico identificador.
- Por exemplo, as notas dos alunos de uma turma so valores
inteiros, e o conjunto desses valores formam um todo. por isso
conveniente represent-los como uma s varivel, com vrios
componentes todos do mesmo tipo.
Esse objectivo pode ser conseguido utilizando uma varivel do
tipo array.
Algoritmos e Programao 49
ARRAYS UNIDIMENSIONAIS (VECTORES)
Os arrays de uma dimenso podem ser entendidos como se
de uma coluna (ou linha) de elementos se tratasse, todos do
mesmo tipo.
- CADA UM DOS ELEMENTOS DE UM ARRAY PODE SER ACEDIDO
INDIVIDUALMENTE, BASTANDO PARA ISSO ESPECIFICAR O NOME DO
ARRAY, SEGUIDO POR UM NDICE ESCRITO ENTRE PARNTESIS RECTOS,
INDICADOR DA POSIO DO ELEMENTO NESSE ARRAY.
- OS ELEMENTOS DE UM ARRAY PODEM SER DE QUALQUER UM DOS TIPOS
ESTUDADOS, DESDE QUE SEJAM TODOS DO MESMO TIPO.
- AO DEFINIR-SE UMA ESTRUTURA DO TIPO ARRAY, E NA LINGUAGEM
ALGORITMICA ADOPTADA, NECESSRIO INDICAR O TIPO DOS SEUS
ELEMENTOS E OS RESPECTIVOS NDICES.
Exemplo:
lista[0..2] : INTEIRO;
vector[0..99] : REAL;
- lista define e declara um tipo de array de 3 elementos inteiros
referenciados pelos ndices 0, 1 e 2.
A varivel LISTA poder ento ser ilustrada da seguinte forma:
LISTA =
| |
| |
| |(
(
(
2
1
0
LISTA
LISTA
LISTA
- OS NDICES DE UM ARRAY TM DE SER DE UM TIPO ORDENADO, COM
UMA GAMA LIMITADA DE VALORES.
Os elementos de um array podem ser usados em expresses,
instrues de atribuio, instrues de leitura e escrita, etc.:
5*lista[2] > 10 LER(lista[2]);
ESCREVER(lista[0]); lista[i-1] 5*lista[i];
50 Algoritmos e Programao
- QUANDO SE ACEDE A UM DADO ELEMENTO DE UM ARRAY, O NDICE QUE
O REFERENCIA PODE SER EXPRESSO COMO UMA CONSTANTE, UMA
VARIVEL OU ATRAVS DE UMA EXPRESSO
- Contudo, o ndice deve ser do tipo correcto.
- Exemplo de instrues que ilustram as vrias indexaes:
N := 2;
Y := lista[N]+lista[2];
Z := lista[(N MOD 2)+1];
Exemplo
1- Desenvolver um Algoritmo que, usando um vector de 5 elementos
do tipo inteiro, faa as seguintes tarefas, pela ordem indicada:
- Leitura de 5 nmeros digitados pelo utilizador;
- Apresentao de forma inversa qual foram digitados (isto ,
mostre em primeiro lugar o ltimo nmero digitado, depois o
penltimo, e por fim o primeiro);
- Apresentao apenas dos nmeros pares digitados;
- Calculo e apresentao da mdia aritmtica dos valores digitados.
NOME: Primeiro de arrays
i,soma, vector[0..4]: INTEIRO;
media:REAL;
INICIO
//leitura dos 5 nmeros
PARA i0 AT 4 PASSO 1 FAZER
ESCREVER(Digite um nmero: );
LER(vector[i]); //leitura do elemento i
FIMPARA
//Apresentao dos valores de trs para a frente
ESCREVER(Valores digitados: );
PARA i0 AT 4 PASSO 1 FAZER
ESCREVER(vector[4-i]);
FIMPARA
//Apresentao apenas dos valores pares
ESCREVER(Valores Pares digitados: );
PARA i0 AT 4 PASSO 1 FAZER
SE (vector[i] MOD 2 = 0) ENTO
ESCREVER(vector[i]);
FIMSE
FIMPARA
Algoritmos e Programao 51
//Calculo e apresentao da mdia dos valores digitados
soma0;
PARA i0 AT 4 PASSO 1 FAZER
soma soma + vector[i];
FIMPARA
media soma / 5
ESCREVER(A mdia dos valores lidos ,media);
FIM.
PASSAGEM DE PARMETROS DO TIPO ARRAY
Os arrays, tal como qualquer outro tipo de dados, podem ser
utilizados como parmetros de Subprogramas.
- Contudo, so sempre tratados como argumentos passados por
referncia (INOUT), sendo que qualquer alterao do seu
contedo dentro de um subprograma tem efeito no array usado
como argumento para esse subprograma.
A utilizao de arrays como parmetros obedece a regras idnticas s
de passagem de parmetros de tipo simples.
- A indicao ao subprograma de que um determinado
argumento do tipo Array feita atravs do uso de [] logo aps
o identificador do array. Exemplo:
SUB LERVEC(INOUT vec[]:INTEIRO): void
- sendo que o uso da palavra INOUT pode ser omitida, uma vez
que os arrays so sempre passados por referncia.
- de notar tambm, que na sintaxe usada, no existe indicao
do tamanho do array. Caber ao programador, fazer passar
tambm essa informao para o interior do subprograma. Ex:
atravs do uso de uma outra varivel de entrada:
SUB LERVEC(INOUT vec[]:INTEIRO,IN nlem:INTEIRO): void
A soluo apresentada, para o exerccio anterior, foi desenvolvida
totalmente no bloco principal do algoritmo. Em seguida feita a
apresentao, recorrendo agora ao uso de subprogramao (que a
forma mais correcta).
52 Algoritmos e Programao
// bloco principal
NOME: Primeiro b de arrays
vector[0..4]: INTEIRO;
media:REAL;
INICIO
//leitura dos 5 nmeros
LERNUMEROS(vector);
//Apresentao dos valores de trs para a frente
ESCREVER(Valores digitados: );
MOSTRARVECTOR1(vector);
//Apresentao apenas dos valores pares
ESCREVER(Valores Pares digitados: );
MOSTRARPARES(vector);
//Calculo e apresentao da mdia dos valores digitados
media MEDIAVECTOR(vector);
ESCREVER(A mdia dos valores lidos ,media);
FIM.
Resultado: a soluo ficou mais pequena e clara, tendo no entanto
agora de se resolver os problemas mais pequenos:
//leitura dos 5 nmeros
SUB LERNUMEROS(INOUT vec[]:INTEIRO): void
i:INTEIRO;
INICIO
PARA i0 AT 4 PASSO 1 FAZER
ESCREVER(Digite um nmero: );
LER(vec[i]); //leitura do elemento i
FIMPARA
FIMSUB
//Apresentao dos valores de trs para a frente
SUB MOSTRARVECTOR1(INOUT vec[]:INTEIRO): void
i:INTEIRO;
INICIO
PARA i0 AT 4 PASSO 1 FAZER
ESCREVER(vec[4-i]);
FIMPARA
FIMSUB
//Apresentao apenas dos valores pares
SUB MOSTRARPARES(INOUT vec[]:INTEIRO): void
i:INTEIRO;
INICIO
PARA i0 AT 4 PASSO 1 FAZER
SE (vec[i] MOD 2 = 0) ENTO
Algoritmos e Programao 53
ESCREVER(vec[i]);
FIMSE
FIMPARA
FIMSUB
//Calculo e devoluo da mdia dos valores digitados
SUB MEDIAVECTOR(INOUT vec[]:INTEIRO): REAL
soma,i:INTEIRO;
INICIO
soma0;
PARA i0 AT 4 PASSO 1 FAZER
soma soma + vec[i];
FIMPARA
RETORNAR soma / 5;
FIMSUB.