Departamento de Engenharia Rural Centro de Ciências Agrárias
Modularização Recursividade
Modularização
Seus programas continuam evoluindo e o código está cada vez maior e mais complexo: o número de funções cresce rapidamente.
Código complexo pode ser difícil de ler, e ainda mais difícil de manter.
Museu do código fonte não modular.
Partes do seu código se repetem ao longo do programa, gerando um emaranhado de instruções.
Uma forma de gerenciar essa complexidade e eliminar certas redundâncias através da modularização.
Modularização
A experiência mostrou que a melhor maneira de desenvolver e manter um grande programa é construí-lo a partir de
Modularização
Dentre as técnicas de programação estruturada,
encontra-se a modularização:
Decompor um programa em uma série de
subprogramas individuais.
A modularização é um método utilizado para
facilitar a construção de grandes programas, através de sua divisão em pequenas etapas (dividir para conquistar)
Entre as principais estratégias da modularização
estão a criação de sub-rotinas e de funções. (ou módulos, subprogramas, etc...)
Modularização
Sub-rotinas e funções são trechos de código que você
usa quando necessário dentro de seu programa.
Estes recursos permitem separar ações comuns e, dessa forma, tornam seu código mais fácil de ler e de manter. Aprender um pouco sobre isto pode tornar sua vida de codificação bem mais fácil!
Programa principal e Subprogramas
a primeira, por onde começa a execução do trabalho,
recebe o nome de programa principal;
as outras são as sub-rotinas e as funções
Seu código terá uma organização um pouco diferenciada do que foi visto até agora, sendo dividido em duas partes:
Modularização e Reuso
A modularização permite o reuso de partes do
programa num mesmo programa ou mesmo em novos programas
As ferramentas ficam em um local
separado. No código do programa principal você só faz referência aos nomes dessas ferramentas.
Modularização e Reuso
Exemplo de oportunidade de reuso: imagine um
trecho de programa que verifica se uma data é valida ou não:
A rotina de verificação de data pode ser usada várias
vezes num mesmo programa (ou em diferentes
Modularização – Outros benefícios
Outras consequências positivas do uso de
modularização é o aumento de clareza e concisão
do programa, pois o comprimento do programa
Modularização – Vantagens
Economia de código:
Escreve-se menos;
Desenvolvimento modularizado:
Pensa-se no algoritmo por partes;
Facilidade de depuração (correção/acompanhamento):
É mais fácil corrigir/detectar um erro apenas uma vez do que dez vezes;
Facilidade de alteração do código:
Se é preciso alterar, altera-se apenas uma vez;
Generalidade de código com o uso de parâmetros:
Escreve-se algoritmos para situações genéricas.
Aumento de produtividade:
Não se empenha recursos para desenvolver soluções já disponíveis;
Modularização
program NOTAS; {sem sub-rotinas ou funções}
var
nota1,nota2: Real;
begin
readln(nota1);
readln(nota2);
writeln((nota1 + nota2) / 2);
Modularização
Como elaborar programas de forma modular?
Cada um de vocês tem um papel nesta
Modularização
Antes de codificar, você deve pensar no sistema como um
conjunto de componentes que realizam serviços específicos, da
forma mais independente possível em relação aos outros
Modularização – Pascal
O Turbo Pascal oferece duas maneiras de se
criar módulos:
Procedimentos
(para a criação de sub-rotinas)Funções
Depois de pensar nos serviços (ou funções) que devem ser executados para a resolução do seu problema, você poderá se preocupar em conhecer os recursos da linguagem de
Modularização – Procedimentos
Um subprograma do tipo PROCEDIMENTO é, na
realidade, um programa com “vida própria”, mas que, para ser processado, tem que ser solicitado
pelo programa principal que o contém, ou por outro subprograma, ou por ele mesmo.
Ao encerrar, o programa segue o fluxo normal
partindo do ponto imediatamente após a chamada da sub-rotina.
Modularização – Procedimentos
Sintaxe para a criação de procedimentos:
Procedure <nome>;
{declaração dos objetos locais ao procedimento (variáveis, constantes, subprogramas, etc}
begin
{comandos do procedimento}
end;
Modularização – Procedimentos
program NOTAS; {sem sub-rotinas ou funções}
var
nota1,nota2: Real;
begin
readln(nota1);
readln(nota2);
writeln((nota1 + nota2) / 2);
Modularização – Procedimentos
Utilizando um módulo do tipo procedimento.
Modularize a
entrada de dados e o processamento!
program NOTAS; {procedimentos}
var
nota1,nota2: Real;
procedure le_Notas; begin readln(NOTA1); readln(NOTA2); end; procedure get_Media; begin
writeln((nota1+ nota2) /2);
end;
begin
le_Notas;
get_Media;
program NOTAS; {procedimentos}
var
nota1,nota2: Real;
procedure le_Notas; begin readln(NOTA1); readln(NOTA2); end; procedure get_Media; begin
writeln((nota1+ nota2) /2);
end; begin le_Notas; get_Media; end.
Modularização – Procedimentos
Modularização – Procedimentos
Seu código imprime a média. Grande coisa. É lamentável, já que você realmente
precisa OBTER a média do aluno e USÁ-LA. Seu código não tem muita utilidade desse jeito, apenas exibindo a média, não é?
A versão atual da função get_Media exibe a média do aluno toda vez que ela é usada (ou chamada). Mas se você precisar obter a média para fazer algo com ela, isto não será possível.
Modularização – Procedimentos
Caso a média do aluno seja 7.0 o programa deve exibir a mensagem: “Aprovado”, caso contrário, exibir a mensagem “Prova Final”.
Modularização – Funções
As funções, embora muito semelhantes aos
procedimentos, têm a característica especial de
retornar ao programa que as chamou um valor
associado ao nome da função.
Esta característica permite uma analogia com o
Modularização – Funções
Sintaxe para a criação de funções:
function <nome>: tipo;
{declaração dos objetos locais à função (variáveis, constantes, subprogramas, etc}
begin
{comandos da função}
end;
Onde: nome é o identificador associado à função; e tipo é o tipo da função, ou seja, o tipo do valor de retorno
Modularização – Procedimentos
Utilizando um módulo do tipo função.
A função get_Media retorna
um valor: a média do aluno.
program NOTAS; {usando um procedimento e uma função}
var
nota1,nota2: Real;
procedure le_Notas;
begin
readln(nota1);
readln(nota2);
end;
function get_Media: Real; var
soma: Real;
begin
soma := (nota1 + nota2);
get_Media := soma / 2; end; begin le_Notas; ifget_Media >=7.0 then writeln('Aprovado') else
writeln('Prova Final');
end.
program NOTAS; {usando um procedimento e uma função}
var
nota1,nota2: Real;
procedure le_Notas;
begin
readln(nota1);
readln(nota2);
end;
function get_Media: Real; var
soma: Real;
begin
soma := (nota1 + nota2);
get_Media := soma / 2; end; begin le_Notas; ifget_Media >=7.0 then writeln('Aprovado') else
writeln('Prova Final');
end.
Modularização – Funções
A entrada dos dados e o cálculo
da média estão “presos” às
Modularização – Funções
Além das duas notas, o programa deverá solicitar o nome do aluno. Após calcular a média, o nome deve ser exibido junto com a
Modularização – Procedimentos
Você deve obter e exibir o nome do aluno! Modifique o procedimento le_Notas, chamando-o de “le_Dados” e inclua uma
variável para o nome do aluno.
programNOTAS;{usando um procedimento e uma função}
var
nota1,nota2: Real; procedurele_Dados; Var nome: String; begin readln(nome); readln(nota1); readln(nota2); end;
functionget_Media:Real; var
soma: Real; begin
soma := (nota1+nota2);
get_Media := soma/2; end;
begin
le_Dados;
writeln('O aluno ', nome, ' esta: ');
ifget_Media >=7.0then
writeln('Aprovado')
else
writeln('Prova Final'); end.
Modularização – Funções
O compilador diz que não conhece a variável
nome
.
Como ele pôde se esquecer dela tão rápido?
Erro de compilação: identificador desconhecido
Modularização – Funções
A média final será calculada como:
media_Final (media + nota_ProvaFinal)/2;
Sua função get_Media não parece resolver este problema, já que usa sempre as variáveis nota1 e nota2.
Modularização – Escopos
As variáveis são acessadas por seus identificadores. O programa principal e os subprogramas podem ter suas próprias declarações de variáveis.
Como, e onde, será feito o acesso a essas variáveis?
Museu do código fonte monolítico. Investigue primeiro o erro de compilação. Depois
resolva a questão do cálculo da média final. Escopo de variáveis
Modularização – Escopo de variáveis
Por exemplo, quando o usuário do seu sistema de notas na primeira versão modularizada
informa a nota1 do aluno, o valor digitado é gravado na variável nota1:
As linguagens de programação registram as variáveis em uma seção da memória chamada de pilha (stack). Esta seção funciona como um bloco de notas.
procedure le_Dados; var
nome: string; begin
readln (nome);
Modularização – Escopo de variáveis
Mas quando você chama um módulo (função ou procedimento), o computador
começa a gravar cada nova variável criada no código do módulo em uma nova folha de papel na pilha:
Quando você cria uma função, o computador cria uma nova lista de variáveis.
Esta nova folha de papel na pilha é uma nova página na pilha. Páginas de pilha gravam todas as novas variáveis que são criadas dentro de um módulo. Tais variáveis são conhecidas como
variáveis locais.
As variáveis que são criadas antes da definição do módulo continuam na pilha e podem ser usadas pelo módulo caso seja necessário: elas estão na página de pilha anterior.
Mas por que o computador grava variáveis desse jeito?
Seu programa cria uma nova página cada vez que ele chama um módulo, permitindo ao módulo ter seu próprio conjunto separado de variáveis. Se o módulo cria uma nova variável para algum cálculo interno, isto é feito em sua página de pilha sem afetar as variáveis já existentes no resto do programa.
Quando uma variável pode ser vista por
Modularização – Escopo de variáveis
Este mecanismo ajuda a manter as coisas
organizadas, mas tem um efeito colateral que
está causando problemas…
Modularização – Escopo de variáveis
Quando você sai de um módulo, as variáveis desse módulo são descartadas.
Cada vez que você chama um módulo, o programa cria uma nova página de pilha para gravar novas variáveis. Mas o que acontece quando o módulo termina sua execução?
O computador “joga fora” a página de pilha do módulo!
Lembre-se: a pilha de páginas existe para gravar variáveis locais que pertencem ao módulo. Essas variáveis não foram projetadas para ser usadas em outros locais do programa porque são locais ao módulo. Toda a razão para a utilização de uma pilha de variáveis é permitir a um módulo criar variáveis locais que são
invisíveis ao resto do programa.
Quando uma variável não pode ser vista por algum código, é dito que ela está “fora do escopo”.
Modularização – Escopo de variáveis
E foi isto que aconteceu com a variável “nome”. A primeira vez que o Pascal a viu foi quando ela foi criada no
procedimento le_Dados. Isto significa que a variável nome foi criada na
página de pilha do procedimento
le_Dados.
Quando o procedimento le_Dados
terminou, sua página de pilha foi
“jogada fora” e o Pascal esqueceu-se
completamente da variável nome. Posteriormente, quando seu código tenta usá-la para alguma coisa, você não teve sorte, pois ela não pôde mais ser encontrada.
Modularização – Escopo de variáveis
programNOTAS; {usando um procedimento e uma função}
var
nota1,nota2: Real;
nome: String; procedurele_Dados; begin readln(nome); readln(nota1); readln(nota2); end; ...
Agora, a variável nome é visível em qualquer parte do código.
Ela possui um escopo diferente do escopo local.
Uma possível solução para o problema da variável nome seria declará-la fora do procedimento le_Dados, junto com as variáveis nota1 e nota2.
Modularização – Escopo de variáveis
Além do escopo local, existe o global.
É o que acontece com as variáveis nota1, nota2
(e nome após a mudança no local de sua declaração)
No escopo global, como o próprio nome diz, a
variável pode ser acessada de qualquer lugar do programa, seja de fora de tudo, dentro de módulos, dentro de laços, tudo.
Modularização – Escopo de variáveis
O escopo local é um tanto relativo. Uma variável
local pode ser acessada de um mesmo nível ou níveis inferiores, mas nunca em níveis superiores
Modularização – Escopo de variáveis
Na versão atual de seu programa, as variáveis nota1, nota2 e nome
foram declaradas fora de todos os módulos.
A variável soma foi declarada no dentro da função get_Media.
Entendendo bem o conceito de escopo, você verá que é possível declarar diferentes variáveis com o
mesmo nome em um mesmo código fonte, desde que em diferentes escopos.
programNOTAS;{usando um procedimento e uma função}
var
nota1,nota2: Real;
nome: String; procedurele_Dados; begin readln(nome); readln(nota1); readln(nota2); end;
functionget_Media:Real; var
soma: Real; begin
soma := (nota1+nota2);
get_Media := soma/2; end;
begin
le_Dados;
writeln('O aluno ', nome, ' esta: ');
ifget_Media >=7.0then
writeln('Aprovado')
else
writeln('Prova Final'); end.
Modularização – Escopo de variáveis
As variáveis NOTA1, NOTA2 e NOME, declaradas
no programa principal são globais.
Modularização – Escopo de variáveis
Referenciar variáveis globais no código de
procedimentos e funções serve para
implementar um mecanismo de transmissão de
informações de um nível mais externo para um
mais interno.
As variáveis locais dos procedimentos e funções
são criadas e alocadas quando da sua ativação e
automaticamente liberadas quando do seu término.
Modularização – Escopo de variáveis
O uso de variáveis globais não constitui, no
entanto, uma boa prática de programação.
No Pascal, um programa não possuirá variáveis
globais quando todas as variáveis forem declaradas após todas as definições de módulos.
program meu_programa;
{importação de units} {definição de constantes}
{definição de funções e procedimentos}
{A partir daqui você poderá declarar suas variáveis}
begin {programa principal}
{instruções do programa principal}
Modularização – Escopo de variáveis
Assim, todos os subprogramas devem apenas
utilizar as variáveis locais, conhecidas dentro dos
mesmos, e a transmissão de informações para
dentro e para fora dos subprogramas deve ser
feita de outra maneira.
Modularização – Escopo de variáveis
A transmissão de informações para o
processamento em subprogramas pode ser feita por meio de parâmetros de transmissão.
Modularização – Parâmetros
Além de evitar problemas com variáveis globais, a
passagem de parâmetros pode tornar os
subprogramas mais genéricos, (portanto com
mais chances de serem reaproveitados):
Formaliza a comunicação entre os módulos;
Permite que um módulo seja utilizado com operandos diferentes (mesmo processamento para diferentes
entradas – reuso flexível do módulo).
Programa principal
Informa_Sabor Calc_Valor_Pizza
Modularização – Parâmetros
Na linguagem Pascal, para criar procedimentos e
funções com parâmetros, basta criar uma lista de parâmetros entre parênteses após o nome do
módulo na etapa de declaração do módulo:
procedure <nome> (lista de parâmetros formais);
Modularização – Parâmetros
A lista de parâmetros tem a seguinte forma:
Parâmetro_1: tipo; parâmetro_2: tipo; ...; parâmetro_n: tipo
Com este recurso você pode redefinir os módulos do seu
programa para que em vez de manipularem variáveis globais, utilizem parâmetros para obter os dados a ser processados:
procedure le_Dados (nome_aluno: String; n1, n2: Real);
Modularização – Parâmetros
Os identificadores dos parâmetros listados no momento em que você declara os procedimentos e as funções, podem ser qualquer nome de identificador válido, e não precisam ser exatamente o nome das variáveis que você utilizará no
programa principal.
Observe que em vez de declarar le_Dados com parâmetros:
nota1, nota2 e nome, foram inventados os parâmetros: n1, n2
e nome_aluno.
procedure le_Dados (nome_aluno: String; n1, n2: Real);
Modularização – Parâmetros
A nova definição dos módulos do seu programa fica assim:
program NOTAS; {usando um procedimento e uma função}
var
nota1,nota2: Real;
nome: String;
procedurele_Dados (nome_aluno: String; n1,n2: Real);
begin
readln(nome_aluno); readln(n1);
readln(n2);
end;
functionget_Media (v1,v2: Real): Real;
var soma: Real; begin soma := (v1 + v2); get_Media := soma /2; end;
Modularização – Escopo de variáveis
program NOTAS; {usando um procedimento e uma função}
procedurele_Dados (nome_aluno: String; n1,n2: Real);
begin
readln(nome_aluno); readln(n1);
readln(n2);
end;
functionget_Media(v1,v2: Real): Real;
var soma: Real; begin soma := (v1 + v2); get_Media := soma/ 2; end; var
nota1,nota2: Real;
nome: String;
Com o uso de parâmetros, você elimina a necessidade de utilizar variáveis globais.
Declare suas variáveis após todas as definições de módulos em seu código fonte. Isto as torna locais ao escopo do programa principal.
Modularização – Parâmetros
No momento em que você for chamar um procedimento ou a função que exige parâmetros, será necessário passar o nome de variáveis ou valores como parâmetros para o módulo:
programNOTAS;{usando um procedimento e uma função}
procedurele_Dados (nome_aluno: String; n1,n2: Real);
begin
readln(nome_aluno); readln(n1);
readln(n2);
end;
functionget_Media(v1,v2: Real): Real;
var soma: Real; begin soma := (v1+v2); get_Media := soma/2; end; var
nota1,nota2: Real;
nome: String;
begin
le_Dados(nome,nota1,nota2); writeln('O aluno ', nome, ' esta: '); if get_Media(nota1,nota2) >= 7.0 then
writeln('Aprovado') else
writeln('Prova Final');
Modularização – Parâmetros
Em relação ao local que os parâmetros aparecem
em seu código, eles são classificados em Formais
ou Reais:
Formais: inseridos na declaração do subprograma; servem para dar forma ao método e permitir que a
concretização dos valores a utilizar seja feita apenas
no momento da chamada.
Reais: listados na chamada para execução do
subprograma; são eles que realmente vão ser utilizados durante a execução do programa.
program NOTAS; {usando um procedimento e uma função}
procedurele_Dados (nome_aluno: String; n1,n2: Real);
begin
readln(nome_aluno); readln(n1);
readln(n2);
end;
functionget_Media(v1,v2: Real): Real;
var soma: Real; begin soma := (v1 + v2); get_Media := soma /2; end; var
nota1,nota2: Real;
nome: String;
begin
le_Dados(nome,nota1,nota2); writeln('O aluno ', nome, ' esta: ');
ifget_Media(nota1,nota2) >=7.0then
writeln('Aprovado')
else
writeln('Prova Final');
end.
Modularização – Parâmetros
A mesma coisa pode ser dita em relação aos parâmetros da função get_Media
Modularização – Parâmetros
A ordem e o tipo dos parâmetros é importante na lista de
parâmetros reais. ... begin le_Dados(nome,nota1,nota2); ... end. ... ... begin le_Dados(nota1,nome,nota2); ... end. ...
writeln('Media do aluno: ',get_media(nota1,nota2):5:2);
Modularização – Funções
Por algum motivo, a variável
nome está vazia e a média do
aluno foi calculada como 0 (zero).
Inserimos esta linha de código ao fim do seu programa para imprimir o valor da média do aluno “Fulano”.
Modularização – Funções
Consultando um especialista em modularização, ele informou que há um problema na declaração dos parâmetros no procedimento le_Dados.
Os parâmetros reais não receberam os valores dos parâmetros formais durante a execução do procedimento le_Dados.
Parece que nome e nome_aluno,
n1 e nota1, n2 e nota2 não se
Modularização – Parâmetros
A passagem de parâmetros pode ser por Valor
ou por Referência, em relação à maneira que os dados serão enviados ao interior dos módulos:
Por valor: as alterações feitas nos parâmetros formais, dentro do subprograma, não se refletem nos
parâmetros reais. O valor do parâmetro real é copiado no parâmetro formal, na chamada do subprograma. Assim, quando a passagem é por valor, isto significa que o parâmetro é de entrada.
Modularização – Parâmetros
Por Referência: toda alteração feita num parâmetro
formal corresponde a mesma alteração feita no seu parâmetro real associado. Assim quando a passagem é por referência, isto significa que o parâmetro é de entrada-saída.
Modularização – Parâmetros
O seu programa declara uma lista de parâmetros
para o procedimento le_Dados.
A estratégia de passagem de parâmetros que foi
utilizada é por valor.
Assim, o procedimento le_Dados recebe uma cópia
dos valores das variáveis nome, nota1 e nota2 (que inicialmente são desconhecidos, já que não foram lidos antes da chamada ao módulo), não faz nada com estes valores, usa os
parâmetros do procedimento para fazer a leitura de dados, mas não retorna com os valores que foram obtidos na leitura de dados nos parâmetros reais.
Modularização – Parâmetros
Um parâmetro passado por valor, funciona como
uma variável ou valor local para o módulo.
Sendo um elemento local, qualquer coisa feita
com os parâmetros não é visível fora do escopo
Modularização – Parâmetros
Para corrigir este problema, você deve declarar
seus parâmetros e dizer que eles serão passados por referência.
Assim, qualquer coisa que for alterada no escopo
do módulo, será transmitida imediatamente para as variáveis que foram usadas como
Modularização – Parâmetros
Declarar um parâmetro que será passado por
referência é muito simples: basta incluir a palavra reservada var antes do nome dos parâmetros que devem ser passados por referência na lista de
parâmetros formais (no local onde você define o seu módulo).
procedure le_Dados (var nome_aluno: String; var n1,n2: Real); begin
readln(nome_aluno); readln(n1);
readln(n2);
end;
Tudo que for feito com estes parâmetros
será refletido na variável que eu usar na
chamada ao módulo.
Modularização – Parâmetros
program EXEMPLO_PASSAGEM_PARAMETROS;
var
N1, N2 : integer;
procedure PROC(X: integer; var Y: integer);
begin X := 1; Y := -1; end; begin N1:=20; N2:=20; PROC(N1,N2);
writeln(N1); {será exibido o valor 20}
writeln(N2); {será exibido o valor -1}
end.
Qualquer valor assumido por X no interior do módulo deixará de existir após o encerramento do procedimento PROC, porém, o parâmetro Y é um parâmetro formal com passagem por referência, as modificações feitas em Y no interior de PROC refletirão na variável N2, que foi utilizada como parâmetro real na chamada a PROC no programa principal.
program NOTAS; {usando um procedimento e uma função}
procedurele_Dados (var nome_aluno: String;var n1,n2: Real);
begin
readln(nome_aluno); readln(n1);
readln(n2);
end;
functionget_Media(v1,v2: Real): Real;
var soma: Real; begin soma := (v1 + v2); get_Media := soma /2; end; var
nota1,nota2: Real;
nome: String;
begin
le_Dados(nome,nota1,nota2); writeln('O aluno ', nome, ' esta: ');
ifget_Media(nota1,nota2) >=7.0 then
writeln('Aprovado')
else
writeln('Prova Final');
writeln('Media do aluno: ',get_media(nota1,nota2):5:2);
end.
Modularização – Parâmetros
A função get_Media não precisa alterar
seus parâmetros, então, deixe-a como está, recebendo parâmetros passados por valor.
programNOTAS;{usando um procedimento e uma função}
procedurele_Dados (var nome_aluno: String;var n1,n2: Real); begin
readln(nome_aluno); readln(n1);
readln(n2);
end;
functionget_Media(v1,v2: Real): Real; var soma: Real; begin soma := (v1+v2); get_Media := soma/2; end; var
nota1,nota2,pfinal: Real;
nome: String;
Modularização – Parâmetros
Agora você pode aproveitar a função get_Media para
calcular a media final, caso o aluno fique de prova final, sem precisar escrever outra função só para isto.
begin
le_Dados(nome,nota1,nota2);
writeln('Media do aluno: ',get_media(nota1,nota2):5:2); writeln('O aluno ', nome, ' esta: ');
ifget_Media(nota1,nota2) >=7.0then
writeln('Aprovado')
else begin
writeln(‘de Prova Final');
writeln(‘Digite a nota da prova Final');
readln(pfinal);
writeln('Media final do aluno: ', get_Media(get_Media(nota1,nota2),pfinal) :5:2);
writeln(‘Situação final: ');
ifget_Media(get_Media(nota1,nota2) ,pfinal) >=5.0then
writeln('Aprovado') else
writeln(‘Reprovado');
end;
Modularização – Parâmetros: Exemplos
Escrever um procedimento chamado DOBRA que multiplique um número inteiro (recebido como parâmetro) por 2.
Escrever um programa para ler um valor inteiro
e, utilizando o procedimento DOBRA, calcular e
Modularização – Parâmetros: Exemplos
program CALCULA_DOBRO;
{Variável global}
var
X: integer;
procedure DOBRA (var NUM: integer);
begin
NUM := NUM * 2 {ponto e vírgula não é obrigatório antes de end}
end; {programa principal} begin readln(X); DOBRA(X); writeln(X); end.
Modularização – Parâmetros: Exemplos
program CALCULA_DOBRO;
{Variável global}
var
X: integer;
procedure DOBRA (var NUM: integer);
begin
NUM := NUM * 2 {ponto e vírgula não é obrigatório antes de end}
end; {Variável local} var X: integer; {programa principal} begin readln(X); DOBRA(X); writeln(X); end.
Neste exemplo, foi utilizada uma variável
global (X). Para não utilizar variáveis
globais, todas as declarações de variáveis deverão ocorrer imediatamente antes do comando begin do programa principal.
Declarar a variável X neste local, faz com que ela seja uma variável local ao programa principal, isto é, visível apenas no escopo do programa principal. Assim, ela não pode ser referenciada dentro de subprogramas diretamente pelo seu nome. Para um módulo manipular o valor da variável X, ele deverá ser capaz de receber essa variável como um parâmetro em sua chamada.
Modularização – Parâmetros: Exemplos
Escrever uma função chamada MAIOR que
receba dois números inteiros e retorne o maior deles.
Escrever um programa para ler dois números
inteiros e, utilizando a função MAIOR, calcular e
Modularização – Parâmetros: Exemplos
program CALCULA_MAIOR;
{Função para cálculo do maior valor}
function MAIOR(NUM1, NUM2: integer): integer;
begin
if (NUM1 > NUM2) then
MAIOR := NUM1 else
MAIOR := NUM2;
end;
{Variáveis locais ao escopo do programa principal}
var X, Y, M: integer; {programa principal} begin readln(X,Y); M := MAIOR(X,Y); writeln(M); end.
Modularização – Parâmetros: Exemplos
Escreva um procedimento que receba uma string
S e a converta para letras maiúsculas.
Faça também uma função que realize o mesmo
serviço do procedimento solicitado no enunciado anterior.
Modularização – Parâmetros: Exemplos
procedure pMaiusc(var S: string);
var i, tam: integer; begin tam := length(S); for i := 1 to tam do S[i] := upcase(S[i]); end;
function fMaiusc(S: string): string;
var i, tam: integer; begin tam := length(S); for i := 1 to tam do S[i] := upcase(S[i]); fMaiusc := S; end;
procedure pMaiuscv2(S: string; var sMaiuscula: string);
var
i, tam: integer;
begin
tam := length(S);
sMaiuscula[0] := S[0]; {iguala o comprimento das strings}
for i := 1 to tam do
sMaiuscula[i] := upcase(S[i]);
Modularização – Parâmetros: Exemplos
program MANIPULA_STRINGS;
procedure pMaiusc(var S: string);
var i, tam: integer; begin tam := length(S); for i := 1 to tam do S[i] := upcase(S[i]); end;
procedure pMaiuscv2(S: string; var sMai: string);
var
i, tam: integer;
begin
tam := length(S);
sMai[0] := S[0]; {iguala o length das duas strings}
for i := 1 to tam do
sMai[i] := upcase(S[i]);
end;
function fMaiusc(S: string):string;
var i, tam: integer; begin tam := length(S); for i := 1 to tam do S[i] := upcase(S[i]); fMaiusc := S; end; {programa principal} var st1, st2, st3: string; mai1,mai2, mai3: string;
begin readln(st1); readln(st2); readln(st3); pMaiusc(st1); mai1 := st1;
writeln('variavel st1 apos a execucao do procedure: ',st1); writeln('variavel mai1 apos a execucao do procedure: ',mai1); writeln;
pMaiuscv2(st2,mai2);
writeln('variavel st2 apos a execucao do procedure: ',st2); writeln('variavel mai2 apos a execucao do procedure: ',mai2); writeln;
mai3 := fMaiusc(st3);
writeln('variavel st3 apos a execucao do procedure: ',st3); writeln('variavel mai3 apos a execucao do procedure: ',mai3);
Recursividade
Existem casos em que um procedimento ou função
chama a si próprio.
Diz-se então que o procedimento ou função é
recursivo.
Uma forma visual de recursão conhecida como efeito Droste.
O triângulo de Sierpinski —uma recursão fechada de triângulos formando uma reticulada geométrica.
Brócolis “Romanesco”: exemplo de vegetal que é formado por estruturas auto similares: estruturas maiores formadas a partir de estruturas menores muito similares entre si.
Recursividade
Por exemplo, o fatorial de um número n pode ser
definido recursivamente, ou seja:
A sequência de Fibonacci também é definida de
forma recursiva:
𝑛! = 𝑛 𝑛 − 1 !,1, 𝑛 = 0𝑛 > 0
Recursividade
Pode-se escrever uma função recursiva em Pascal
que traduz esta definição matemática:
function FAT(n: integer): integer;
begin if n = 0 then FAT := 1 else FAT := N * FAT(N-1); end;
Recursividade
Para executar uma função recursiva, o
computador deverá resolver todas as chamadas recursivas antes de retornar um valor na primeira chamada da função.
Isto gera uma série de chamadas que, se
corretamente implementadas, terminará
retornando o valor especificado no caso básico da definição da função (caso em que n = 0, para a
Recursividade
function FAT(n: integer): integer;
begin if n = 0 then FAT := 1 else FAT := N * FAT(N-1); end;
Referências
FARRER, H.; BECKER, C. G.; FARIA, E. C.; MATOS, H. F.; et al. Algoritmos estruturados. 3ed, Ed. LTC, 1999. ISBN: 9788521611806.
GUIMARÃES, A. M.; LAGES, N. A. C.; Algoritmos e estruturas de dados. 1ed, Ed. LTC, 1994. ISBN: 9788521603788.
FARRER, H.; BECKER, C. G.; FARIA, E. C.; MATOS, H. F.; et al. Pascal estruturado. 3ed, Ed. LTC, 1999. ISBN: 9788521611745.
Velloso, F. C.; Informática: Conceitos Básicos. 7ed, Ed. Campus, 2004. ISBN: 9788535215366.
http://www.hkbu.edu.hk/~bba_ism/ISM2110/index.htmj