Upload
letram
View
215
Download
1
Embed Size (px)
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