Tópicos avançados sobre funções (cont.) - Técnico Lisboa ·...

Preview:

Citation preview

Instituto Superior Técnico,

Dep. de Engenharia Mecânica - ACCAII

Tópicos avançados sobre funções (cont.)

• Definição de function handle

• Utilização de function handles

• Funções anónimas

• Funções em que os argumentos são funções (function functions)

• Funções com número de parâmetros variáveis

• Nº de parâmetros de entrada variável

• Nº de parâmetros de saída variável

• Funções encadeadas (nested functions)

• Funções privadas

• Funções recursivas

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Funções com número de parâmetros variáveis

2

• As funções na sua definição podem ter um número de

parâmetros de entrada e saída variáveis:

• Existe um cell array pré-definido (built-in) que permite

armazenar um número de parâmetros de entrada variável:

• Denominação: varargin

• Existe um cell array pré-definido (built-in) que permite

armazenar um número de parâmetros de saída variável:

• Denominação: varargout

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Funções com número de parâmetros variáveis

3

• Existe uma função pré-definida (built-in) que retorna o

número de argumentos de entrada com que a função foi

chamada:

• Denominação: nargin

• Existe uma função pré-definida (built-in) que retorna o

número de argumentos de saída que a função deve devolver:

• Denominação: nargout

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Nº de parâmetros de saída variável

4

• As funções na sua definição podem ter um número de

parâmetros de entrada e saída variáveis:

• Existe um cell array pré-definido (built-in) que permite

armazenar um número de parâmetros de entrada variável:

• Denominação: varargin

• Existe um cell array pré-definido (built-in) que permite

armazenar um número de parâmetros de saída variável:

• Denominação: varargout

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Nº de parâmetros de saída variável

5

Problema 1:

Escreva uma função que receba um array como argumento e que devolva uma string contendo uma das seguintes hipóteses: escalar, vector, matriz. Existe um ou dois argumentos saída opcionais que retornam a dimensão do argumento de entrada, quando este for um vector ou uma matriz.

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 6

Nº de parâmetros de saída variável• Problema 1 (codificação):

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Nº de parâmetros de saída variável

7

>> typesize(10)

ans =

escalar

>> [tipo , comp] = typesize([1:1:10])

tipo =

vector

comp =

10

>> [tipo , lin , col] = typesize(ones(3,4))

tipo =

matriz

lin =

3

col =

4

Problema 1 (exemplos de execução:

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Nº de parâmetros de saída variável

8

Problema 1:

Escreva uma função que receba um array como argumento e que devolva uma string contendo uma das seguintes hipóteses: escalar, vector, matriz. Existe um ou dois argumentos saída opcionais que retornam a dimensão do argumento de entrada, quando este for um vector ou uma matriz.

Neste problema 1 assumiu-se que os argumentos de saída opcionais

podiam ser um ou dois!

Assuma agora, que no Problema 2, o argumento opcional é apenas um !

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 9

Nº de parâmetros de saída variável• Problema 2 (codificação):

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Nº de parâmetros de saída variável

10

>> [tipo , dim] = typesize_2(ones(5,6))

tipo =

matriz

dim =

5 6

>> [tipo] = typesize_2(ones(5,6))

tipo =

matriz

>> [tipo , dim, zzz] = typesize_2(ones(5,6))

Error in ==> typesize_2 at 4

[r c] = size(inputval);

??? Output argument "varargout{2}" (and maybe others) not

assigned during call to

"D:\Users\Miguel\Documents\MATLAB\Aulas\CP_2009_2010\AT19\

typesize_2.m>typesize_2".

Problema 2 (exemplos de execução:

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Nº de parâmetros de saída variável

11

• A função nargout pode ser utilizada para determinar

quantos argumentos de saída foram utilizados na

chamada a uma função.

Problema 3:

Escreva uma função denominada mysize que receba um array e que devolva o número de linhas, o número de colunas e opcionalmente o número de elementos que o array contem.

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 12

Nº de parâmetros de saída variável• Problema 3 (codificação):

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Nº de parâmetros de saída variável

13

>> [r c] = mysize(zeros(3,5))

r =

3

c =

5

>> [r c elem] = mysize(zeros(3,5))

r =

3

c =

5

elem =

15

Problema 3 (exemplos de execução:

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Nº de parâmetros de saída variável

14

Problema 4:

Escreva uma função denominada mysize_2 que receba um array e que se comporte exactamente como a função size pré-definida no MATLAB.

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 15

Nº de parâmetros de saída variável• Problema 4 (codificação):

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Nº de parâmetros de saída variável

16

>> [dim]=mysize_2(zeros(3,5))

dim =

3 5

>> [lin col]=mysize_2(zeros(3,5))

lin =

3

col =

5

Problema 4 (exemplos de execução:

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Funções encadeadas (nested functions)

17

• Funções encadeadas significa que uma função está definida

dentro do corpo de outra função:

• Neste caso todas as funções devem terminar com a palavra chave end.

• Formato geral de funções encadeadas:

Cabeçalho da função exterior

Corpo da função exterior

Cabeçalho da função interior

Corpo da função interior

end % da função interior

Continuação do corpo da função exterior

end % da função exterior

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 18

Funções encadeadas (nested functions)

host_function

nested_function_2

nested_function_1

Variables defined in the host

function are visible inside any

nested functions.

end % host_function

end % nested_function_1

end % nested_function_2

Variables defined within nested

functions are not visible in the

host function.

nested_function_2 can be

called from within

host_function or

nested_function_1.

nested_function_1 can be

called from within

host_function or

nested_function_2.

As variáveis definidas na função

principal são visíveis em todas as

funções internas.

funcao_principal

func_interna_1

end % func_interna_1

func_interna_2

end % func_interna_2

end % funcao_principal

As variáveis definidas nas funções

internas não são visíveis na função

principal.

func_interna_1 pode ser

chamada por funcao_principal

e por func_interna_2

func_interna_2 pode ser

chamada por funcao_principal

e por func_interna_1

Regras de âmbito:

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Funções encadeadas (nested functions)

19

• Funções encadeadas (exemplo 1):

>> outvol=nestedvolume(1,2,2)

outvol =

4

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 20

Funções encadeadas (nested functions)

function res = testa_internas

% Nivel mais alto. Define variaveis

a = 1; b = 2; x = 0; y = 9;

% Escreve valor das variaveis antes de chamar funcao1

fprintf('Antes de chamar funcao1:\n');

fprintf('a, b, x, y = %2d %2d %2d %2d\n', a, b, x, y);

% Chama funcao interna funcao1

x = funcao1(x);

% Escreve valor das variaveis depois de chamar funcao1

fprintf('\nDepois de chamar funcao1:\n');

fprintf('a, b, x, y = %2d %2d %2d %2d\n', a, b, x, y);

%Declara funcao interna funcao1

function res = funcao1(y)

% Variaveis no inicio de funcao1

fprintf('\nNo inicio de funcao1:\n');

fprintf('a, b, x, y = %2d %2d %2d %2d\n', a, b, x, y);

Funções encadeadas (exemplo 2):

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 21

Funções encadeadas (nested functions)

y = y + 5;

a = a + 1;

res = y;

% Variaveis no fim de funcao1

fprintf('\nNo fim de funcao1:\n');

fprintf('a, b, x, y = %2d %2d %2d %2d\n', a, b, x, y);

end % funcao funcao1

end % funcao testa_internas

retorna:>> testa_internas

Antes de chamar funcao1:

a, b, x, y = 1 2 0 9

No inicio de funcao1:

a, b, x, y = 1 2 0 0

No fim de funcao1:

a, b, x, y = 2 2 0 5

Depois de chamar funcao1:

a, b, x, y = 2 2 5 9

Funções encadeadas (exemplo 2) (cont.):

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 22

Funções privadas

• As funções privadas estão em sub-directorias com o nome de private. Estas funções só são visíveis nas funções da directoria de raíz (parent directory).

• Estas directorias com o nome específico de private podem ser criadas pelo programador, utilizando os procedimentos habituais de criação de directorias ou folders no computador.

• Estas directorias private não devem ser colocadas na path!

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 23

Avaliação de funções

1. O Matlab verifica se existe uma função interna com um dado nome. Se existir, executa-a.

2. É procurada uma subfunção com o nome dado. Se existir, executa essa subfunção.

3. É procurada uma função com o nome dado na directoria private. Será executada se existir.

4. É procurada uma função com o nome dado na directoria de trabalho. Se existir, é executada.

5. Finalmente, é procurado no MATLAB path. Se existir uma função no path, será executada.

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 24

Funções recursivas

• Considere-se a função para calcular o factorial

• Pode ser definida de forma recursiva:

1 se is 0!

1 2 ... se > 0

nn

n n

1 se is 0!

( 1)! se > 0

nn

n n n

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 25

Funções recursivas

• Uma definição recursiva tem duas partes

1. Uma âncora ou base (caso mais simples)O valor é especificado para um ou mais valores dos parâmetro(s)

2. Um passo inductivo ou recursivoO valor do parâmetro é especificado em função dos valores ou parâmetros mais simples.

1 se is 0!

( 1)! se > 0

nn

n n n

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 26

Funções recursivas

• Para calcular 5! seguem-se os seguintes passos:

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 27

Funções recursivas

• Código da função factorial, programada de forma recursiva:function resultado = factorial(n)

if (n < 0 || round(n)~=n)

error('O argumento deve ser um inteiro >=0.');

elseif (n == 0)

resultado = 1;

else

resultado = n * factorial(n-1);

end

Caso mais simples

Passo inductivo

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 28

Funções recursivas

• Sequência de passos recursivos quando é chamadanumero = factorial(4);

Chamadas

recursivas

sucessivas

Execução da função recursiva:

resultado = resultado =

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 29

Funções recursivas

• Quando factorial(n–1) envia por fim o valor 0 como parâmetro, é executada a instrução âncora

• Não há mais chamadas recursivas

. . .

Execução da função recursiva:

resultado = resultado = resultado=1

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 30

Funções recursivas

• Os valores calculados vão sendo retornados:

126

24

Execução da função recursiva:

resultado=1resultado =resultado =resultado =resultado =

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 31

• A famosa sequência de Fibonacci, foi descrita por Leonardo de Pisa, também conhecido como Fibonacci (1170-1250) , para descrever o crescimento de uma população de coelhos. Os números descrevem o número de casais numa população de coelhos depois de n meses, considerando um conjunto pressupostos.(ver: http://pt.wikipedia.org/wiki/N%C3%BAmero_de_Fibonacci)

A sequência é dada pela seguinte expressão:

Primeiros termos: (0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...),

Funções recursivas Exercício

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 32

• Implemente uma função recursiva (denominada fibo.m) que calcule o enésimo termo da sequência de Fibonacci.

• Teste a função com um script.

Funções recursivas Exercício

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 33

Funções recursivas Exercício

function [termo_n] = fibo(n)

% A função FIBO recebe

% como parâmetro de entrada:

% um valor n inteiro >=1;

% A função retorna:

% o enésimo termo da sequência de Fibonacci.

if (n < 0 || round(n) ~= n)

error('O valor tem que ser um inteiro maior ou igual a 1.');

end

switch (n)

case 0,

termo_n = 0;

case 1,

termo_n = 1;

otherwise,

termo_n = fibo(n-1) + fibo(n-2);

end

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010 34

Funções recursivas Exercício

%Este script testa a função FIBO

clc; clear all; close all;

disp('Este script testa a função FIBO');

%pede o termo N até ao qual se pretende calcular a sequência

valor_incorrecto = true;

while (valor_incorrecto)

N = input(['Introduza o termo N até onde pretende calcular ', ...

'a seq. de Fibonacci: ']);

valor_incorrecto = (N < 0 || round(N) ~= N);

end

seq=[];

for k=0:N

seq=[seq,fibo(k)];

end

figure(20);

stem(0:N, seq), grid on;

title(['Sequência de Fibonacci até ao termo ' int2str(N)]);

Miguel Pedro Silva – José Borges Computação e Programação 2009 / 2010

Referências

35

• Capítulo 9 de Stormy Attaway (2009), “Matlab: A Practical Introduction to Programming and Problem Solving”, Elsevier.

• Getting started with MATLAB: http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/getstart.pdf

Recommended