Algoritmos e Estruturas de Dados I
Subalgoritmos:
Funções e Procedimentos
Profa. Márcia Cristina Moraes Profa. Milene Selbach Silveira
Material para estudo:
Forbellone, A. e Eberspächer, H. (2005)
capítulo 6 (conceitos de modularização e escopo de variáveis)
Subalgoritmos
Muitos problemas com soluções complexas podem ser divididos, sucessivamente em problemas menores, com lógica mais
simples e de compreensão mais fácil. Em vez de escrever um algoritmo grande,
escrevem-se vários algoritmos menores, os quais em conjunto resolvem o problema
proposto.
Subalgoritmos e Modularização
Trechos de algoritmo que efetuam cálculos determinados, são chamados de
subalgoritmos.
O processo de dividir problemas grandes em um conjunto de problemas menores é
chamado de modularização.
Modularização: vantagens
Dividir problemas grandes em vários problemas
menores, de menor complexidade, principalmente por terem um número pequeno de variáveis e poucos
caminhos de controle (caminhos do início ao fim do programa).
Possibilidade de usar soluções gerais para classes de problemas em lugar de soluções específicas para
problemas particulares.
Evitar a repetição dentro de um mesmo algoritmo, de uma sequência de ações em diferentes pontos.
Permite delimitar o escopo (nível de abrangência) de variáveis.
[Orth 2001]
Modularização: escopo de váriáveis
As variáveis definidas no interior de um módulo são denominadas de variáveis locais. As
variáveis deste tipo são ativadas somente quando aquele módulo começa a ser executado. Ocupam memória somente até o final da execução do
módulo ao qual pertencem. Isto permite uma
otimização do uso da memória.
Modularização:
Variáveis Locais x Variáveis Globais
Variáveis Globais: possuem seu valor válido durante todo o algoritmo
Variáveis Locais: somente são válidas dentro do subalgoritmo ao qual fazem parte
Algoritmo Exemplo inteiro: a, b, c
Início
inteiro: x, y, z ....
Fim
Variáveis globais, válidas para o Algoritmo exemplo e todos os sub- algoritmos que podem ser criados
Variáveis locais, somente são válidas para o algoritmo exemplo, não valem para nenhum subalgoritmo criado
Até o momento somente estávamos usando variáveis globais, agora vamos usar variáveis locais.
Subalgoritmos: tipos
A maioria das linguagens possui 2 formas de implementar e usar subalgoritmos
(módulos):
Função: calculam um único valor em função de um ou mais parâmetros recebidos
Procedimento: podem calcular um número
qualquer de valores, calculados ou não em
função dos parâmetros recebidos
Função
tipo Função NomeF(tipo: Arg1, tipo: Arg2, ..., tipo: Argn) Início
{Definição das variáveis locais}
...
{conjunto de comandos}
NomeF Expressão Retorne
Fim
Retorno para o programa principal da expressão calculada na função
Função
Tipo: tipo de retorno da função (qualquer um dos tipos existentes, por exemplo, inteiro, real, literal)
NomeF: nome da função
O número de argumentos depende do que se quer fazer na função. O nome do argumento sempre vem precedido do seu tipo
NomeF Expressão: indica o retorno da
expressão calculada na função para o programa principal
Retorne: indica o término da execução do
subalgoritmo e o retorno do controle para o
programa principal
Exemplo
Inteiro Função Soma(inteiro: a, b) Início
inteiro: res res a + b Soma res Retorne
Fim
a e b: argumentos de entrada
res: variável local, armazena o valor que será retornado pela função
Como o valor calculado retorna para o algoritmo principal?
Soma res Retorne
Como passamos os argumentos para a função? Através de passagem de
parâmetros.
Passagem por valor: passa o valor das variáveis para os argumentos
inteiro Função Soma(inteiro: a, inteiro: b)
a e b são argumentos passados por valores do tipo inteiro
Função Soma também pode ser escrita da seguinte maneira:
▪ Inteiro Função Soma(inteiro: a,b)
▪ Quando mais de um valor é do mesmo tipo eles podem ser separados por vírgulas
Passagem de Parâmetros
Passagem de Parâmetros
Passagem por referência: passa o
endereço de memória da variável para o argumento
Inteiro Função Soma2(inteiro: ref a, inteiro: b)
a é um argumento passado por referência e b é um argumento passado por valor
Isto significa que a recebe/armazena um endereço de memória relacionada a uma variável e não o valor de uma variável
Vamos com calma!!
Aprofundaremos este conceito quando virmos Procedimentos
Por enquanto só vimos a declaração de uma função
Para que ela seja efetivamente usada ela precisa ser declarada e chamada
Iremos chamar a função dentro do algoritmo principal da seguinte maneira:
NomeF(parâmetros)
Parâmetros são os nomes das variáveis que queremos enviar para a função
Chamada da Função
Passo a passo
Algoritmo Principal Inteiro: x, y, resultado Início
leia(x, y)
resultado Soma(x, y) escreva(resultado)
Fim
Inteiro Função Soma (inteiro: a, b) Início
inteiro: res res a + b Soma res Retorne
Fim
10 3
Chamada da Função
Chama a função soma passando o valor de x que é 10 e o valor de y que é 3
Sabe que é passagem por valor Porque não tem ref na frente de a e nem de b
Algoritmo Principal Inteiro: x, y, resultado Início
leia(x, y)
resultado Soma(x, y) escreva(resultado)
Fim
Inteiro Função Soma (inteiro: a, b) Início
inteiro: res res a + b Soma res Retorne
Fim
Algoritmo Principal Inteiro: x, y, resultado Início
leia(x, y)
resultado Soma(x, y) escreva(resultado)
Fim
Inteiro Função Soma (inteiro: a, b) Início
inteiro: res res a + b Soma res Retorne
Fim
Chamada da Função
a recebe o valor de x, ou seja 10 b recebe o valor de y ou seja 3 Declara a variável res que é uma variável local, ou seja, somente é válida dentro da função Soma Parâmetros a e b somente são válidos dentro da função Soma
Chamada da Função
res recebe a soma de 10 e 3, ou seja, recebe 13
Algoritmo Principal Inteiro: x, y, resultado Início
leia(x, y)
resultado Soma(x, y) escreva(resultado)
Fim
Inteiro Função Soma (inteiro: a, b) Início
inteiro: res res a + b Soma res Retorne
Fim
Chamada da Função
Nome da função recebe o valor a ser retornado
Algoritmo Principal Inteiro: x, y, resultado Início
leia(x, y)
resultado Soma(x, y) escreva(resultado)
Fim
Inteiro Função Soma (inteiro: a, b) Início
inteiro: res res a + b Soma res Retorne
Fim
Chamada da Função
Retorna o controle para o programa principal
Algoritmo Principal Inteiro: x, y, resultado Início
leia(x, y)
resultado Soma(x, y) escreva(resultado)
Fim
Inteiro Função Soma (inteiro: a, b) Início
inteiro: res res a + b Soma res Retorne
Fim
Chamada da Função
Resultado recebe o valor retornado por Soma, ou seja, 13
Algoritmo Principal Inteiro: x, y, resultado Início
leia(x, y)
resultado Soma(x, y) escreva(resultado)
Fim
Inteiro Função Soma (inteiro: a, b) Início
inteiro: res res a + b Soma res Retorne
Fim
Chamada da Função
Escreve o valor de resultado, ou seja, 13
Algoritmo Principal Inteiro: x, y, resultado Início
leia(x, y)
resultado Soma(x, y) escreva(resultado) Fim
Inteiro Função Soma (inteiro: a, b) Início
inteiro: res res a + b Soma res Retorne
Fim
Chamada da Função
Poderia substituir estas 2 linhas por
escreva (Soma(x,y))
Algoritmo Principal Inteiro: x, y, resultado Início
leia(x, y)
resultado Soma(x, y) escreva(resultado)
Fim
Inteiro Função Soma (inteiro: a, b) Início
inteiro: res res a + b Soma res Retorne
Fim
Exercício
Faça um algoritmo que lê um número inteiro e chama uma função que verifica se este é um número par. O algoritmo deve escrever o resultado da função (se retornou que o número é par ou não).
Faça, também, a função que recebe o valor inteiro e
verifica se ele é um número par. A função deve retornar 1
caso o número seja par e 0 no caso contrário.
Procedimento
Pode calcular um número qualquer de valores
Pode retornar valores se os mesmos são passados por referência para o
subalgoritmo, caso contrário, o procedimento
não retorna nenhum valor
Procedimento
Procedimento NomeP(tipo: Arg1, tipo: Arg2,..., tipo:Argn) Início
{Definição das variáveis locais}
...
Fim
Pode retornar valores nos argumentos desde que eles sejam passados por referência para o procedimento. Neste caso deve-se ter ao final do procedimento uma atribuição para os argumentos que se deseja
retornar valores calculados dentro do procedimento.
Pode retornar valores nos argumentos desde que eles sejam passados por referência para o procedimento. Neste caso deve-se ter ao final do procedimento uma atribuição para os argumentos que se deseja retornar valores calculados dentro do procedimento.
Diferença para a função??
Procedimento
Procedimento NomeP(tipo: Arg1, tipo: Arg2,..., tipo:Argn) Início
{Definição das variáveis locais}
...
Fim
Procedimento
NomeP: nome do procedimento
Da mesma forma que na função o
procedimento também deve ser chamado no algoritmo principal
NomeP(parâmetros)
Na hora que o procedimento é chamado, os valores (parâmetros) da chamada são
passados para os argumentos
correspondentes
Procedimento
Argumentos de definição e parâmetros de
chamada devem corresponder em número, e tipo e estar na mesma ordem
Enquanto os argumentos de definição devem ser obrigatoriamente variáveis, os
parâmetros de chamada podem ser
expressões.
Exemplo – Procedimento que não retorna valor
Procedimento Soma(inteiro: a, b) Início
inteiro: res res a + b
Escreva (“Resultado da soma = ”, res)
Fim
Chamada do Procedimento Soma
Algoritmo Principal inteiro: x, y
Início
Leia(x, y) Soma(x,y) Escreva(x,y) Fim
Valores de x e y não são alterados, pois a passagem de parâmetros é por valor
Chamada do procedimento soma passando os parâmetros x e y por valor
Passo a Passo (1/6)
Algoritmo Principal inteiro: x, y
Início
leia(x, y) Soma(x, y) escreva(x,y) Fim
Procedimento Soma(inteiro: a, b) Início
inteiro: res res a + b Escreva(res) Fim
10 3
Chama o procedimento soma passando o valor de x que é 10 e o valor de y que é 3
Sabe que é passagem por valor Porque não tem ref na frente de a e nem de b
Algoritmo Principal inteiro: x, y
Início
leia(x, y) Soma(x, y) escreva(x,y) Fim
Procedimento Soma(inteiro: a, b) Início
inteiro: res res a + b Escreva(res) Fim
Passo a Passo (2/6)
Algoritmo Principal inteiro: x, y
Início
leia(x, y) Soma(x, y) escreva(x,y) Fim
Procedimento Soma(inteiro: a, b) Início
inteiro: res res a + b Escreva(res) Fim
a recebe o valor de x, ou seja 10 b recebe o valor de y, ou seja 3 Declara a variável res que é uma variável local, ou seja, somente é valida dentro da função Soma
Passo a Passo (3/6)
res recebe a soma de 10 e 3, ou seja, recebe 13
Algoritmo Principal inteiro: x, y
Início
leia(x, y) Soma(x, y) escreva(x,y) Fim
Procedimento Soma(inteiro: a, b) Início
inteiro: res res a + b Escreva(res) Fim
Passo a Passo (4/6)
Escreve o resultado
Algoritmo Principal inteiro: x, y
Início
leia(x, y) Soma(x, y) escreva(x,y) Fim
Procedimento Soma(inteiro: a, b) Início
inteiro: res res a + b Escreva(res) Fim
Passo a Passo (5/6)
Escreve o valor de x e y, ou seja, 10 e 3
Algoritmo Principal inteiro: x, y
Início
leia(x, y) Soma(x, y) escreva(x,y) Fim
Procedimento Soma(inteiro: a, b) Início
inteiro: res res a + b Escreva(res) Fim
Passo a Passo (6/6)
Retomando...
Passagem por referência: passa o endereço de memória da variável para o argumento
Procedimento Soma2(inteiro: ref a, inteiro: b)
a é um argumento passado por referência e b é um argumento passado por valor
Isto significa que a recebe/armazena um endereço de memória relacionada a uma variável e não o valor de uma variável
O valor do argumento a retorna alterado para o
algoritmo principal
Exemplo – procedimento retorna valor na variável a
Procedimento Soma2(inteiro: ref a, b) Início
res: inteiro res a + b a res
Fim
Passagem por Referência:
Recebe o endereço de memória da variável
Chamada do Procedimento Soma2
Algoritmo Principal inteiro: x, y
Início
Leia(x, y)
Soma2(x,y) Escreva(x,y) Fim
Valor de x retorna alterado, não é mais o valor que possuía antes da chamada
Valor de y volta inalterado, pois foi passado por valor
Chamada do procedimento Soma2 passando os parâmetros x e y
Passo a Passo - Soma2 (1/5)
Algoritmo Principal inteiro: x, y
Início
leia(x, y) Soma2(x, y) escreva(x,y) Fim
Procedimento Soma2(inteiro: ref a, b) Início
inteiro: res res a + b a res Fim
10 3
Algoritmo Principal inteiro: x, y
Início
leia(x, y)
Soma2(x, y) escreva(x,y) Fim
Procedimento Soma2(inteiro: ref a, b) Início
inteiro: res res a + b a res Fim
Chamada do procedimento Soma2 Passa x por referência e y por valor
Endereço de x vai para a Valor de y vai para b
x y
[150] 10 3 [200]
a b
[150] 3
Passo a Passo - Soma2 (2/5)
res recebe o conteúdo do endereço de memória apontado por a mais o valor de b.
Conteúdo apontado por a é 10 mais valor de b que é 3
x y
[150] 10 3 [200]
a b res [150] 3 13
Algoritmo Principal inteiro: x, y
Início
leia(x, y) Soma2(x, y) escreva(x,y) Fim
Procedimento Soma2(inteiro: ref a, b) Início
inteiro: res res a + b a res
Fim
Passo a Passo - Soma2 (3/5)
Endereço de memória apontado por a recebe o valor de res
x y
[150] 13 3 [200]
a b res [150] 3 13
Algoritmo Principal inteiro: x, y
Início
leia(x, y) Soma2(x, y) escreva(x,y) Fim
Procedimento Soma2(inteiro: ref a, b) Início
inteiro: res res a + b a res Fim
Passo a Passo - Soma2 (4/5)
x y
[150] 13 3 [200]
Escreve o valor de x e de y
Valor de x foi alterado dentro do procedimento!
Algoritmo Principal inteiro: x, y
Início
leia(x, y) Soma2(x, y) escreva(x,y) Fim
Procedimento Soma2(inteiro: ref a, b) Início
inteiro: res res a + b a res Fim
Passo a Passo - Soma2 (5/5)
Exercício 1
Faça um procedimento que dado dois valores N e X, escreve os N primeiros pares acima de X.
Passagem
por valor ou
por referência?
Exercício 2
Faça um procedimento que recebe 2 parâmetros do tipo inteiro e retorna os valores dos parâmetros trocados para o algoritmo principal. Construa o algoritmo principal e faça uma chamada este
procedimento.
E
agora?
Exercício 3
Faça um procedimento que recebe 3 valores inteiros por parâmetro e retorna-os ordenados em ordem crescente. Use o procedimento
definido no exercício 2. Construa o algoritmo principal e faça uma chamada a este
procedimento.
Bibliografia
Orth, Afonso Inácio. Algoritmos e Programação. Editora AIO. 2001.