4.3 MATLAB学习笔记之程序设计-函数文件

函数文件

许多时候希望将特定的算法写成函数的形式,以提高程序的可重用性和程序设计的效率。

函数文件定义了输出参数和输入参数的对应关系,以方便外部调用。事实上,MATLAB 提供的 标准函数都是由函数文件定义的。

1 函数文件的基本结构

函数文件由function 语句引导,其基本结构如下:

function 输出形参表 = 函数名(输入形参表)

注释说明部分

函数体语句

其中,

  • 以 function 开头的一行为引导行,表示定义一个函数。

  • 函数名的命名规则与变量名相同。

  • 在函数定义时,输入输出参数没有分配存储空间,所以称为形式参数,简称形参。

  • 当有多个形参时,形参之间用逗号分隔,组成形参表。

  • 当输出形参多于一个时,则应该用方括号括起来, 构成一个输出矩阵。

说明:

(1)关于函数文件名。函数文件名通常由函数名再加上扩展名.m 组成,不过函数文件名与函数名也可以不相同。当两者不同时,MATLAB将忽略函数名,调用时使用函数文件名。为理解和记忆的方便, 一般建议函数文件名和函数名统一。

(2)关于注释说明部分。注释说明包括如下3部分内容。

① 紧随函数文件引导行之后以%开头的第一注释行。这一行一般包括大写的函数文件名和函数功能简要描述,供lookfor 关键词查询和help 在线帮助用。

② 第一注释行及之后连续的注释行。通常包括函数输入输出参数的含义及调用格式说明等信息,构成全部在线帮助文本

③ 与在线帮助文本相隔一空行的注释行。包括函数文件编写和修改的信息,如作者、修改日期、版本等内容,用于软件档案管理。

(3)关于 return 语句。如果在函数文件中插入了return 语句,则执行到该语句就结束函数的执行,程序流程转至调用该函数的位置。通常,在函数文件中也可不使用return 语句,这时在被调用函数执行完成后自动返回。

例1 编写函数文件,求半径为r的圆的面积和周长。

函数文件如下:

function [s,p]=fcircle(r)
%CIRCLE calculate the area and perimeter of a circle of radii r
%r      圆半径
%s      圆面积
%p      圆周长
 
%2016年9月20日编
s=pi*r*r;
p=2*pi*r;

将以上函数文件以文件名fcircle.m存盘,然后在MATLAB命令行窗口调用该函数。

>> [s,p]=fcircle(10)

s =
 314.1593

p =
  62.8319
2 函数调用
1.函数调用的格式

函数文件建立好后,就可以调用该函数了,调用格式如下:

[输出实参表]=函数名(输入实参表)

在调用函数时,函数输入输出参数称为实际参数,简称实参。

要注意的是,函数调用时各实参出现的顺序、个数,应与函数定义时形参的顺序、个数一致,否则会出错。

函数调用时, 先将实参传递给相应的形参,从而实现参数传递,然后再执行函数的功能。

例2 利用函数文件,实现直角坐标(x,y)与极坐标(ρ,θ)之间的转换。

首先编写函数文件tran.m。

function [rho,theta]=tran(x,y)
rho=sqrt(x*x+y*y);
theta=atan(y/x);

再在脚本文件main1.m中调用函数文件tran.m。

x=input('Please input x=');
y=input('Please input y=');
[rho,the]=tran(x,y);
disp(['rho=',num2str(rho)])
disp(['the=',num2str(the)])

最后在命令行窗口运行脚本文件main1.m。

>> main1
Please  input  x=45
Please  input   y=45

rho     =
63.6396 
the    =
0.7854

实际上,MATLAB 提供了直角坐标与极坐标之间转换的函数,分别如下。

(1) [th,r]=cart2pol(x,y) : 将直角坐标转换为极坐标。

(2)[x,y]=pol2cart(th,r) : 将极坐标转换为直角坐标。

例如:

>>[rho,the]=cart2pol(45,45) 
rho     =
63.6396 
the    =
0.7854
2.函数的递归调用

在 MATLAB中,函数可以嵌套调用,即一个函数可以调用其他函数,甚至调用它自身。

一个函数调用它自身称为函数的递归调用。

例3 利用函数的递归调用,求n!。

采用递归调用的函数文件factor.m如下:

function f=factor(n)
if n<=1
  f=1;
else
  f=factor(n-1)*n;  %递归调用求(n-1)!
end

在脚本文件main2.m中调用函数文件factor.m,求s = 1! + 2! + 3! + 4! + 5!。

s=0;
n=input('Please input n=');
for i=1:n
  s=s+factor(i);
end
disp(['1到',num2str(n),'的阶乘和为:',num2str(s)])

在命令行窗口运行脚本文件:

>>main2
Please   input   n=5
15的阶乘和为:153

例4 任意排列问题。

MATLAB 提供的函数 randperm(n)可以产生一个从整数1到整数 n的任意排列。编写一个函数来实现 randperm(n) 函数的功能,即给出一个由任意数组成的行向量,然后产生这个行向量元素的任意排列。

① 函数用循环结构。★★

function Y=rndprm1(X)
%RNDPRM1  用for循环产生一个行向量的任意排列
%RNDPRM1(X)产生行向量X的任意排列

[m,n]=size(X);
if m>1
  error('RNDPRM1 accepts as inputs only vectors');
end

Y=[];             %从一个空矩阵开始
l=n;              %X的元素个数

for i=1:n
  k=1+fix(l*rand);     %随机选择Y的下一个元素的位置
  x=X(k);          %被选择的元素
  Y=[Y,x];         %将x添加到Y中
  X(k)=[];         %从X中删除x元素  
  l=l-1  ;         %更新X的元素个数
end

② 函数用递归调用。

function Y=rndprm2(X)
%RNDPRM2   用递归调用产生一个行向量的任意排列
%RNDPRM2(X)产生一个X的任意排列

[m,n]=size(X);
l=n;
if m>1
  error('RNDPRM2 accepts as inputs only vectors')
end

if n<=1
  Y=X;
else

k=1+fix(l*rand);     %随机选择Y的下一个元素的位置
x=X(k);          %被选择的元素
X(k)=[];          %从X中删除x元素  
  Z=rndprm2(X);       %将剩下的元素随机排列
  Y=[Z,x];          %构造输出向量
  l=l-1;
end

③ 在命令行窗口调用所定义的函数,命令如下:

>> rndprm1([34,6,3,54,2,5,454])
>> rndprm2([34,6,3,54,2,5,454])
>> rndprm1('apple')
>> rndprm2('apple')
3 函数参数的可调性

MATLAB 在函数调用上有一个特点,就是函数所传递参数数目的可调性★。凭借这一点,一个函数可完成多种功能。

在调用函数时,MATLAB 用两个预定义变量nargin 和nargout 分别记录调用该函数时的输入实参和输出实参的个数。

只要在函数文件中包含这两个变量,就可以准确地知道该函数文件 被调用时的输入/输出参数个数,从而决定函数如何进行处理。

例5 nargin用法示例。

建立函数文件charray.m。

function fout=charray(a,b,c)
if nargin==1
  fout=a;
elseif nargin==2
  fout=a+b;
elseif nargin==3
  fout=(a*b*c)/2;
end

建立脚本文件mydemo.m。

a=1:3;b=a';
x=charray(a);
y=charray(a,b');
z=charray(a,b,3);
disp(['x=   ',num2str(x)])
disp(['y=   ',num2str(y)])
disp(['z=   ',num2str(z)])

执行脚本文件mydemo.m 后的输出结果如下:

X=    1  2  3
Y=    2  4  6
Z=    21
4.全局变量与局部变量

在MATLAB中,函数文件中的变量是局部的,与其他函数文件及MATLAB工作空间相互隔离,即在一个函数文件中定义的变量不能被另一个函数文件引用。

如果在若干函数中,都把某一变量定义为全局变量,那么这些函数将共用这个变量。

全局变量的作用域是整个MATLAB 工作空间,即全程有效,所有的函数都可以对它进行存取和修改,因此,定义全局变量是函数间传递信息的一种手段。

全局变量用global 命令定义,格式如下:

global 变量名

例6 全局变量应用示例。

先建立函数文件wadd.m,该函数将输入的参数加权相加。

function f=wadd(x,y)
global ALPHA BETA
f=ALPHA*x+BETA*y;

在命令行窗口中输入命令并得到输出结果。

>> global ALPHA BETA
>> ALPHA=1;
>> BETA=2;
>> s=wadd(1,2)

在实际程序设计时,可在所有需要调用全局变量的函数中定义全局变量,这样就可实现数据共享。

在函数文件中,全局变量的定义语句应放在变量使用之前,为了便于了解所有的全局变量,一般把全局变量的定义语句放在文件的前部。为了在工作空间中使用全局变量,也要定义全局变量。

值得指出的是,在程序设计中,全局变量固然可以带来某些方便,但却破坏了函数对变量的封装,降低了程序的可读性,因此,在结构化程序设计中,全局变量是不受欢迎的,尤其当程序较大,子程序较多时,全局变量将给程序调试和维护带来不便,故不提倡使用全局变量

如果一定要用全局变量,最好给它起一个能反映变量含义的名字,以免和其他变量混淆。

Matlab学习笔记内容来源于《MATLAB程序设计与应用 第三版》刘卫国主编

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值