Chap 5 MATLAB函数
5.1 函数简介
一个典型的MATLAB函数如下:
function f = fact(n)
% H1 Comment Line
% Other Comment Line1
% Other Comment Line...
f = prod(1:n);
end
function
关键字标志着函数的开始,=
左边是输出列表,=
右边是函数名,紧跟函数名的是输入列表。
function
下的第一个行注释称为H1注释行
,应当是对本函数功能的总结,可以通过lookfor
命令搜索到。
从H1注释行
到第一个空行或者第一个可执行语句间的注释可以通过help
命令搜索到。
lookfor fact;
help fact;
function 关键字(必需) | 对关键字使用小写字符。 |
---|---|
输出参数(可选) | 如果您的函数返回一个输出,则您可以在 function 关键字后面指定输出名称。function myOutput = myFunction(x) 如果您的函数返回多个输出,请将输出名称括在方括号中。function [one,two,three] = myFunction(x) 如果没有输出,您可以将其忽略。function myFunction(x) 您也可以使用空的方括号。function [] = myFunction(x) |
函数名称(必需) | 有效的函数名字遵守与变量名称相同的规则。它们必须以字母开头,可以包含字母、数字或下划线。注意为避免混淆,对函数文件及函数文件内的第一个函数使用相同名称。MATLAB 将您的程序与文件名而不是函数名称相关联。脚本文件不能与文件中的函数具有相同的名称。 |
输入参数(可选) | 如果您的函数接受任何输入,请在函数名称之后将输入名称括在圆括号中。用逗号将各个输入隔开。function y = myFunction(one,two,three) 如果没有输入,可以忽略圆括号。 |
函数以end
语句、文件末尾或局部函数的定义行结束。虽然end
有时不是必须的,但一般都会加上end
提高代码可读性。
5.2 按值传递变量
MATLAB函数的参数传递的机制是按值传递,但其实MATLAB会分析传入的参数是否在函数内被修改了,如果没有修改就不会对参数进行复制,而是使用外面的变量;如果修改了复制操作才会执行。
5.3 选择性参数
许多MATLAB函数支持选择性输入参数和输出参数,比如对于plot
函数来说,既可以输入两个参数,也可以输入八个参数,对于max
的输出,可以选择输出一个,也可以输出两个。
MATLAB中有专门的函数用于 获取选择性参数的信息 和 报告其错误:
Name | Function |
---|---|
nargin | 实际输入参数的个数 |
nargout | 实际输出参数的个数 |
nargchk | 如果调用参数过多或过少会返回一个标准错误信息 |
error | 显示错误信息,并中止函数以免产生这个错误 |
warning | 显示警告信息,并继续执行函数 |
inputname | 返回对特定参数个数的实际变量名 |
注意:inputname
返回的是***函数传入参数的工作区变量的名称***,如果输入参数是数字、表达式或索引表达式而不是变量,则它没有名称。要用inputname(n)
来获取某个参数的名称,例如打印输入参数的变量名:
function argTest(arg1, arg2, arg3)
% disp every arg in
narginchk(1, 3);
% use modern usage above instead of below
% message = nargchk(minargs, maxargs, nargin);
% error(message);
for i = 1 : nargin
disp(inputname(i));
end
end
以前一般是将nrgchk
和error
结合着用,但现在MATLAB推荐使用narginchk
和nargoutchk
来代替,如果输入参数过多或过少,matlab会有报错:
错误使用 argTest (第 2 行)
输入参数的数目不足。
5.4 全局变量
将变量声明为全局变量的关键字是global
:
% fun1.mat
global x;
x = 5;
% fun2.mat
global x;
disp(x);
全局变量占用的是全局内存,而非本地工作区,如果多个函数都将特定的变量名称声明为 global
,则它们都共享该变量的一个副本。
好的编程习惯:
- 将全局变量声明在函数的开头,有助于区分本地变量
- 使用全局变量前需要先声明
- 利用全局变量进行大规模数据的交换
**注意:**如果首次发出 global
语句时尚不存在全局变量,则此语句初始化为空 0x0
矩阵。
全局变量的清除:
- 要从所有工作区中清除全局变量,请使用
clear global
variable
。 - 要从当前工作区而不从其他工作区中清除全局变量,请使用
clear
variable
。
5.5 持久变量
持久变量是函数内的局部变量,但调用完之后值不会被清除,而是保留了下来。声明持久变量的关键字是persistent
。
当 MATLAB 首次遇到特定 persistent
语句时,它将持久变量初始化为空矩阵 ([]
)。通常函数会检查持久变量是否为空,如果是,则初始化该持久变量:
function myFun()
persistent n
if isempty(n)
n = 0;
end
n = n+1;
end
% 持久变量也会被清除
clear myFun
注意:
- 持久变量需要先声明再引用
- 要清除持久变量,请使用
clear
清楚变量所在的函数。
5.6 函数的函数(function functions)
函数的函数指的是函数的输入参数中还有其他的函数。
例如fzero()
函数用于找到传递给它的函数值为0的自变量,如:
fzero('cos', [0 pi]) % ans=1.5708
eval(expression)
函数可以对一个表达式求值,指定为字符向量或字符串标量。如:
eval('cos(pi)') %ans =-1
feval()
函数使用函数名称对输入求值,feval()
的作用等效为函数句柄。
y = feval('round',pi)
更多类似的函数有:
Function | Describe |
---|---|
fminbnd(fun, x1, x2) | 查找单变量函数在给定区间内的最小值 |
quad(fun, x1, x2) | 求函数在给定区间内的数值积分,推荐使用integral 代替 |
ezplot(fun, x1, x2) | 画出函数在给定区间内的图像, 更推荐使用fplot |
fplot(fun, [x1, x2]) | 画出函数在给定区间内的图像,默认区间是[-5, 5] |
5.7 局部函数、嵌套函数和私有函数
5.7.1 局部函数
MATLAB函数文件可以包含多个函数。在函数文件中,第一个函数称为主函数。此函数对其他文件中的函数可见。而文件中的其他函数称为局部函数,它们可以任意顺序出现在主函数后面。局部函数仅对同一文件中的其他函数可见。它们等效于其他编程语言的子例程,有时被称为子函数。
function [avg, med] = mystats(x)
n = length(x);
avg = mymean(x,n);
med = mymedian(x,n);
end
function a = mymean(v,n)
% MYMEAN Example of a local function.
a = sum(v)/n;
end
function m = mymedian(v,n)
% MYMEDIAN Another example of a local function.
w = sort(v);
if rem(n,2) == 1
m = w((n + 1)/2);
else
m = (w(n/2) + w(n/2 + 1))/2;
end
end
5.7.2 嵌套函数
嵌套函数是完全包含在父函数内的函数:
function parent
disp('This is the parent function')
nestedfx
function nestedfx
disp('This is the nested function')
end
end
嵌套函数与其他类型的函数的主要区别是,嵌套函数可以访问和修改在其父函数中定义的变量。
注意:
- 不能在任何 MATLAB® 程序控制语句内定义嵌套函数,例如
if/elseif/else
、switch/case
、for
、while
或try/catch
。
嵌套函数的可见性:
每个函数都有特定的作用域,即可以看到该函数的一组其他函数。嵌套函数在以下位置可用:
- 高级别的函数能调用只低一级的嵌套函数。(在下面的代码中,函数
A
可以调用B
或D
,但不能调用C
或E
。) - 同级别的嵌套函数可以相互调用。(函数
B
可以调用D
,而D
可以调用B
。) - 低级别的嵌套函数可以调用高级别的函数。(函数
C
可以调用B
或D
,但不能调用E
。)
function A(x, y) % Main function
B(x,y)
D(y)
function B(x,y) % Nested in A
C(x)
D(y)
function C(x) % Nested in B
D(x)
end
end
function D(x) % Nested in A
E(x)
function E(x) % Nested in D
disp(x)
end
end
end
5.7.3 私有函数
可以将函数存储在名称为 private
的子文件夹中,这样该函数就指定为了私有函数。这样,仅 private
子文件夹紧邻的上一级文件夹中的函数和脚本可使用该函数。即使MATLAB强调不要将private
文件夹添加到路径中,但即使添加到路径中,非private
紧邻的上一级文件夹仍然调用不了私有函数。
虽然不能从命令行或 private
文件夹父级外部的函数中调用私有函数,但可以访问它的帮助:
help private/findme
5.7.4 函数的调用顺序
- 变量。如果有与函数同名的变量则会隐藏该函数
- 当前函数内的嵌套函数
- 当前文件内的局部函数
- 私有函数
- 当前文件夹中的函数
- 路径中其他位置的函数
参考资料:
[1] Matlab programming for engineers second edition, Stephen J.Chapman著,邢军树、郑碧波译
[2] MATLAB官方文档