28
7 de Abril de 20 05 Funções, Expressões e E xcepções 1 Funções, Expressões e Excepções Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

Embed Size (px)

Citation preview

Page 1: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 1

Funções, Expressões e Excepções

Pedro BarahonaDI/FCT/UNL

Abril 2004

Page 2: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 2

Funções e Passagem de Parâmetros• Em muitos casos, ao invocar-se uma função pretende-se

obter não apenas um mas vários resultados.• Este requisito é tratado diferentemente em diferentes

linguagens de programação, dependendo em grande parte da forma como são passados os parâmetros de uma função.

• Em OCTAVE, os parâmetros são passados exclusivamente por valor (com uma excepção - nomes de funções).

• Isto quer dizer, que ao especificar-se uma variável no parâmetro de uma função a invocar, o que se passa para a função é o valor da variável.

• Durante a função, a variável não pode ser alterada no programa que invoca a função!

Page 3: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 3

Passagem de Parâmetros por Valor• Exemplo: Consideremos a função

function y = f(x) x = 2*x y = xendfunction;

• Se chamada com o valor x = 5, durante a computação da função, esse valor é duplicado e retornado.

• Por exemplo, se invocarmos a função na sequência (pode ser ao terminal)

..., x = 5; z = f(x); x, z, ...

os valores de x e y reportados no terminal são x = 5 e z = 10.

Page 4: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 4

Passagem de Parâmetros por Valor• Exemplo: ..., x = 5; z = f(x); x, z, ...

function y = f(x) x = 2*x; y = x;endfunction;

A computação da função f pode ser assim explicado: 1. Quando começa a ser executada a função f, é criada uma nova variável x, que

é local à função f, e que não se confunde com a variável x do programa.2. O valor inicial da variável x local é o valor da variável do programa que é

passsada como parâmetro (e que por acaso se chama x).3. A instrução x=2*x apenas envolve a variável local x, que passa a valer 10.4. Na instrução y=2*x, é a nova variável local que é considerada, e portanto, y =

10, valor esse retornado.5. No “programa principal” esse valor é atribuído à variável z.

Page 5: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 5

Passagem de Parâmetros por Referência• Outras linguagens (Pascal, C, C++, ...) permitem a passagem de

parâmetros por referência, i.e. é passada a referência à variável do programa principal, que pode ser alterada pela função.

• Por exemplo se o parâmetro x fosse passado por referência (indicado com uma notação fictícia)

..., x = 5; z = f(x); x, z, ...function y = f(ref x) x = 2*x; y = x;endfunction;

os valores de x e y reportados no terminal seriam • x = 10 (sendo passada por referência, a variável x referida na

função é a mesma variável que a variável x do programa); e• z = 10

Page 6: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 6

Funções com Múltiplos Resultados• A passagem de parâmetros por referência permite que uma

função (ou procedimento) passe vários valores para o programa que a invocou. Basta passar por referência as variáveis onde esses valores devem ser “colocados”.

• O Octave, não suporta passagem de parâmetros por referência. A computação de vários resultados numa função é conseguida pela computação de um vector de resultados.

• Por exemplo, se se pretender que a função f, com argumento x, retorne dois valores, f1 e f2, especifica-se a função como

function [f1,f2] = f(x) ... f1 = ...; f2 = ...; ...endfunction;

Page 7: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 7

Exemplo: maior_alcance_ffunction [dist, angulo] = maior_alcance_f(vi, ka); dist = 0; angulo = 0; for alfa = 0:90 x = alcance(vi,alfa,ka); if x > dist dist = x; angulo = alfa; endif; endfor;endfunction;

• A função maior_alcance_f apresentada abaixo é exactamente equivalente ao programa maior_alcance anterior, com a natural diferença de entrada e saída de parâmetros, podendo ser invocada como, por exemplo.

[d,a] = maior_alcance_f(20, 1);

Page 8: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 8

Funções Booleanas (Predicados) e Mistas• A função anterior facilmente alterada para determinar se

existem velocidades e ângulos iniciais para se atingir uma determinada distância d.

• Neste caso, o objectivo é múltiplo:

– Em primeiro lugar saber se a distância é atingida;

– Se a distância for atingida então indicar a velocidade e o ângulo iniciais.

• Desta forma, para além das velocidade e ângulo iniciais, a função deve retornar um valor booleano que indica se a distância foi atingida ou não.

Page 9: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 9

Exemplo: função atinge_1• Esse valor booleano é mantido pela variável atingida na função

apresentada abaixo:

function [vi, angulo, atingida] = atinge_1(ka, d); atingida = false; for v = 18:22 for alfa = 20:70 x = alcance(v,alfa,ka); if abs(x-d) < 0.1

vi = v; angulo = alfa;

atingida = true endif; endfor;

endfor;endfunction;

Page 10: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 10

Expressões Booleanas• Este enunciado, embora correcto, é algo ineficiente, já que após a

descoberta da velocidade e ângulo iniciais adequados todas as restantes trajectórias são ainda calculadas!

• Esta ineficiência pode ser corrigida se se alterarem os ciclos “para” por ciclos “enquanto”, mas impondo na condição de entrada que não tenha sido ainda descoberta uma solução.

• Essa condição pode ser especificada através de uma expressão booleana, resultante da conjunção de duas expressões booleanas mais simples

– A limitação normal do número de ciclos; e– A variável booleana, atingida, que é falsa enquanto não tiver

sido encontrada uma solução

Page 11: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 11

Expressões Booleanas: função atinge_2 function [vi, angulo, atingida] = atinge_2(ka, d); atingida = false; v = 18; while v <= 22 & ! atingida alfa = 20; while alfa <= 70 & ! atingida x = alcance(vi,alfa,ka); atingida = abs(x-d) < 0.001 if atingida

vi = v; angulo = alfa;

endif; alfa = alfa+1; endwhile;

v = v+1; endwhile;

endfunction;

Page 12: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 12

Expressões Booleanas• Expressões booleanas podem ser construidas recursivamente a

partir de outras mais simples com os operadores booleanos de– Conjunção, “e” ou “and”, expressa como & em OCTAVE

– Disjunção, “ou” ou “or”, expressa como | em OCTAVE

– Negação, “não” ou “not”, expressa como ! em OCTAVE

• As variáveis booleanas podem tomar os valores verdade ou falso. Em OCTAVE, que só considera variáveis “numéricas”, 0 corresponde a falso e qualquer outro valor a verdade!

• De notar que uma variável booleana pode ser atribuído o valor booleano de uma comparação numérica. Por exemplo:

encontrada = (x > xmin & y > ymax)

Page 13: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 13

Excepções (em ciclos)• Embora as expressões booleanas sejam muito convenientes e

permitam escrever programas muito compactos, neste caso a passagem de ciclos “para” para ciclos “enquanto” torna os programas menos “naturais”.

• Uma forma mais natural de expressar a intenção de descobrir a solução é indicar que se pretende percorrer todo o intervalo de possibilidades, excepto se se encontrar uma solução!

• A especificação de excepções é possível em muitas linguagens de programação. No Octave utiliza-se a instrução “break”, para se terminar excepcionalmente um ciclo.

Page 14: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 14

Excepções (em ciclos) ... encontrada = 0; vi = 1; while vi <= 20 & !encontrada ... if condição encontrada = 1; endif; ... vi = vi + 1; endwhile; ...

... for vi = 1:20 ... if condição break; endif; ... endfor; ...

• Por exemplo,

em vez da forma

pode utilizar-se a forma mais simples

Page 15: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 15

Excepções (em ciclos)• Infelizmente, a explicitação de excepções não conduz sempre a

uma grande simplificação da especificação global do programa.

• No caso corrente, como existem dois ciclos, ao sair do ciclo interno (de alfa) é necessário verificar se se deve igualmente sair do ciclo externo (em v).

• Em geral, é conveniente saber se o ciclo terminou de uma forma “normal” ou “excepcional”, pelo que é conveniente continuar a utilizar uma variável booleana para o efeito.

• Por exemplo, os dois ciclos anteriores (em v e alfa) podem ser especificados com excepções break na forma apresentada de seguida:

Page 16: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 16

Excepções (em ciclos) : função atinge_3 function [vi, angulo, atingida] = atinge_3(ka, d); atingida = false; for v = 18:20 for alfa = 20:70 x = alcance(v,alfa,ka); atingida = abs(x-dist) < 0.1; if atingida break endif; endfor;

if atingida break endif; endfor;

vi = v; angulo = alfa; endfunction;

Page 17: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 17

Excepções (em funções)• Se, como é o caso corrente, existirem vários ciclos no interior de

uma função, e se se detectar no interior do ciclo mais interno que o objectivo da função já foi atingido, existe um mecanismo de excepção, através da instrução “return”, que permite terminar a função imediatamente.

• Assim, podem imediatamente terminar-se todos os ciclos, sem se ter de verificar para cada um se o ciclo imediatamente interno terminou com uma excepção ou não.

• No entanto, poderá ter interesse informar o programa (ou função) que chama a função que pode terminar excepcionalmente, se a sua terminação foi normal ou não, o que pode ser feito através de uma variável adicional que é retornada no valor da função.

Page 18: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 18

Excepções (em funções): função atinge_4 function [vi, angulo, atingida] = atinge_4(ka, d); atingida = false; for v = 1:20 for alfa = 1:90 x = alcance(vi,alfa,ka); atingida = abs(x-dist) < 0.1; if atingida

vi = v; angulo = alfa; return endif; endfor; endfor;

endfunction;

Page 19: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 19

Um Pequeno Problema• Em muitas situações, nomeadamente no corpo de ciclos, pretende-

se trocar o valor de duas variáveis, A e B, ou sejaA B.

• Por hipótese, façamos A = 2 e B = 5. O problema é que ao fazer-se uma atribuição, por exemplo

A B

perde-se o valor inicial de A (fica A=B=5) e a atribuição seguinte, B A, mantém a situação. A forma mais simples de resolver este problema é utilizar um avariável secundária onde se guarda o valor inicial de A. As instruções seguintes resolvem pois o problema

C A % C = 2A B % A = 5 B C % B = 2

Page 20: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 20

Programas e Funções• Como visto em exemplos anteriores, um programa pode ser

considerado como o encadeamento de diversas funções, isto é, no corpo de uma função são chamadas outras funções.

• Um programa pode pois ser estruturado de forma a ser composto por várias funções, “como na matemática”. Por exemplo,

tg(x) = sin(x) / cos(x).• Em algumas linguagens de programação, nomeadamente naquelas

em que as funções só podem retornar um valor, em vez de funções são usados procedimentos, mas a filosofia de encadeamento é semelhante.

• De notar que o programa programa principal, pode ele próprio ser visto como uma função.

Page 21: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 21

Funções Recursivas• Um caso particular ocorre quando as funções se chamam a si

próprias, isto é, quando as funções são recursivas.• Talvez o exemplo mais simples seja o da função factorial, que

pode ser definida (incompletamente) comofact(n) = n * fact(n-1)

• Nestas condições, tal como nos ciclos, levanta-se o problema da terminação. Se uma função se chama a si própria, existe o risco de a computação se tornar infinita (entrar em ciclo fechado ou “loop”).

• É pois condição necessária para evitar estes ciclos infinitos que sejam definidas e testadas em primeiro lugar as condições de fim da recursividade.

Page 22: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 22

Funções Recursivas• Em geral, a recursividade é feita com base num conjunto

recursivo (indutivo), definido através de cláusulas de– base; um ou vários elementos de base (que fecham a recursão) – recursão: uma definição recursiva que permite a obtenção de

elementos a partir de outros elementos.• Num grande número de casos, o conjunto recursivo utilizado é o

conjunto dos numeros inteiros, em que– 1 (ou 0) é um número inteiro (cláusula de base)– Se i é inteiro, i+1 também é inteiro (cláusula de recursão)

• Tendo em conta esta estrutura recursiva, podemos definir (correctamente) a função factorial tendo em conta a cláusula de base e a cláusula recursiva

Page 23: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 23

Função Factorial• A função factorial pode ser definida (em pseudo-código) como função fact(n) se n = 0 então % elemento base fact 1 senão % definição recursiva fact n * fact(n-1) fimse; fimfunção;• Em Octave, a definição é semelhante function f = fact(n); if n == 0 % elemento base f = 1 else % definição recursiva f = n * fact(n-1) endif; endfunction;

Page 24: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 24

Limites à Recursividade• De notar que para prevenir os ciclos infinitos, o Octave tem

uma variável prédefinida, max_recursion_depth, que limita o número de chamadas recursivas de uma função.

• Por omissão (“default”), o valor da variável é 256, pelo que não se pode calcular fact(260) sem alterar o valor da variável.

• Existem várias outras funções recursivas em que pode existir mais do que um elemento base ou em que o conjunto recursivo é mais difícil de definir. Em qualquer caso é essencial definir a condição de terminação.

• Para exemplificar estas funções, estudamos de seguida – a determinação dos números de Fibonacci e – o cálculo do maior divisor comum entre dois números.

Page 25: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 25

Função Fibonacci (Recursiva)• Fibonacci (matemático da Renascença italiana) estabeleceu uma

série curiosa de números para modelar o número de casais de coelhos em sucessivas gerações. Em cada geração, o número pode ser obtido através dos das 2 gerações anteriores através de

fib(n) = fib(n-1) + fib(n-2)

• Assumindo que nas primeiras duas gerações só existe um casal de coelhos, os sucessivos números de Fibonacci são

1,1,2,3,5,8,13,21,34,55,89, ...

• Estes números ocorrem em vários processos biológicos (e não só), por exemplo, no número de pétalas de algumas flores.

• A sua determinação recursiva impõe o cálculo directo do valor para 2 elementos de base (a 1ª e a 2ª geração).

Page 26: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 26

Função Fibonacci (Recursiva)• Em Octave, a definição do números de Fibonacci pode ser

feita muito facilmente como function f = fib(n); if n == 1 % 1º elemento base f = 1; elseif n == 2 % 2º elemento base f = 1; else % definição recursiva f = fib(n-1) * fib(n-2); endif; endfunction;

• Como é fácil de constatar, se o número n inicial fôr maior ou igual a 1, a recursão termina. No entanto, se se chamar fib(0) a computação não termina (em Octave termina quando o número de chamadas recursivas exceder o valor da variável max_recursion_depth)!

Page 27: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 27

Função Máximo Divisor Comum (Recursiva)• Como se sabe, o máximo divisor comum (mdc) entre dois

números m e n é também um divisor da sua diferença, m-n. Por exemplo, o mdc de 60 e 36 é 12, que divide 24 = 60-36.

• Por outro lado, o mdc dos dois números m e n é ainda o mdc do menor número (n) com a diferença (m-n). Se houvesse um divisor comum maior, ele seria igualmente divisor de n, contrariamente à hipótese.

• Assim, pode determinar-se o mdc de dois números através da determinação do mdc de números cada vez menores. A computação termina quando os números forem iguais, caso em que o mdc é esse número.

• Por exemplo: 60-36 =24 ; 36-24=12; 24-12=12; 12 = 12 !

Page 28: 7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004

7 de Abril de 2005 Funções, Expressões e Excepções 28

Função Máximo Divisor Comum (Recursiva)

• Em Octave, pode determinar-se o maior divisor comum de dois números com a função seguinte

function d = mdc_rec(m,n); if m == n d = m; else if m-n >= n d = mdc_rec(m-n,n); else d = mdc_rec(n,m-n); endif; endif; endfunction;

• De notar que na chamada, o 1º argumento (m) é sempre maior ou igual que o 2º (n), de forma a garantir que m-n seja positivo!