Upload
dangnhan
View
217
Download
0
Embed Size (px)
Citation preview
Departamento de Engenharia Rural
Centro de Ciências Agrárias
Programação I
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 pedaços pequenos e simples de código, ou módulos.
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:
Eles são executados sempre que chamados .
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 programas).
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 diminui com o uso de módulos.
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);
end.
Modularização
Como elaborar programas de forma modular?
Cada um de vocês tem um papel nesta
empresa
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 componentes.
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 programação que irá usar para implementar os módulos.
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;
Onde: nome é o identificador associado ao procedimento
Modularização – Procedimentos
program NOTAS; {sem sub-rotinas ou funções}
var
nota1,nota2: Real;
begin
readln(nota1);
readln(nota2);
writeln((nota1 + nota2) / 2);
end.
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;
end.
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
Modularização – Funções
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 conceito de Função da Matemática.
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;
if get_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;
if get_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 variáveis: nota1 e nota2.
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 situação do aluno (Aprovado/Prova Final).
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.
program NOTAS; {usando um procedimento e uma função}
var nota1,nota2: Real; procedure le_Dados; Var nome: String; begin readln(nome); readln(nota1); readln(nota2); end; function get_Media: Real;
var
soma: Real;
begin
soma := (nota1 + nota2);
get_Media := soma / 2;
end; begin le_Dados; writeln('O aluno ', nome, ' esta: '); if get_Media >= 7.0 then 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.
get_Media := (nota1 + nota2)/2;
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
Escopo de identificadores e parâmetros
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 algum código, diz-se que ela está “no escopo”.
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
program NOTAS; {usando um procedimento e uma função}
var nota1,nota2: Real; nome: String; procedure le_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. (Retirando sua declaração de dentro do procedimento le_Dados)
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.
program NOTAS; {usando um procedimento e uma função}
var nota1,nota2: Real; nome: String; procedure le_Dados; begin readln(nome); readln(nota1); readln(nota2); end; function get_Media: Real;
var
soma: Real;
begin
soma := (nota1 + nota2);
get_Media := soma / 2;
end; begin le_Dados; writeln('O aluno ', nome, ' esta: '); if get_Media >= 7.0 then 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.
A variável soma é local à função get_Media.
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} end.
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.
...R$ 18.00
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
Imprime_Cupom
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); function <nome> (lista de parâmetros formais): tipo da função ;
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); function get_Media(V1, V2: Real): 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); function get_Media(V1, V2: Real): 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;
procedure le_Dados (nome_aluno: String; n1,n2: Real);
begin
readln(nome_aluno);
readln(n1);
readln(n2);
end;
function get_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}
procedure le_Dados (nome_aluno: String; n1,n2: Real);
begin
readln(nome_aluno);
readln(n1);
readln(n2);
end;
function get_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:
program NOTAS; {usando um procedimento e uma função}
procedure le_Dados (nome_aluno: String; n1,n2: Real); begin readln(nome_aluno); readln(n1); readln(n2); end; function get_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'); end.
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}
procedure le_Dados (nome_aluno: String; n1,n2: Real); begin readln(nome_aluno); readln(n1); readln(n2); end; function get_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'); 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
comunicaram da forma pretendida.
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 do módulo.
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 parâmetros reais na chamada do módulo.
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}
procedure le_Dados (var nome_aluno: String; var n1,n2: Real);
begin
readln(nome_aluno);
readln(n1);
readln(n2);
end;
function get_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');
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.
program NOTAS; {usando um procedimento e uma função}
procedure le_Dados (var nome_aluno: String; var n1,n2: Real);
begin
readln(nome_aluno);
readln(n1);
readln(n2);
end;
function get_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: ');
if get_Media(nota1,nota2) >= 7.0 then
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: ');
if get_Media(get_Media(nota1,nota2) ,pfinal) >= 5.0 then
writeln('Aprovado')
else
writeln(‘Reprovado');
end;
end.
Modularização – Funções
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 exibir o dobro do mesmo.
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 exibir o maior valor entre os números lidos.
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]); end;
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); end.
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, 𝑛 = 0𝑛 𝑛 − 1 !, 𝑛 > 0
𝑓(𝑥) = 1, 0 < 𝑥 < 3𝑓 𝑥 − 1 + 𝑓(𝑥 − 2), 𝑥 ≥ 3
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;
Observe que não há iteração no código!
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 função fatorial).
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
MAURI, G. R.; Notas de aula de Programação I. 2010.