Matlab程序设计.docx
- 文档编号:3745622
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:19
- 大小:60.58KB
Matlab程序设计.docx
《Matlab程序设计.docx》由会员分享,可在线阅读,更多相关《Matlab程序设计.docx(19页珍藏版)》请在冰豆网上搜索。
Matlab程序设计
第四章程序设计
4.1设计初步
4.1.1脚本文件和函数文件定义——MATLAB的两类M文件
(1)脚本文件:
将本要在MATLAB环境下直接输入的语句,放在一个以.m为后缀的文件中,称脚本文件.如,可用任意编辑软件或在MATLAB中选“文件”下“New”调用自已的编辑软件,编辑完毕后,“save”新文件在\matlab11\work子目录下即可。
有了脚本文件,可直接在MATLAB中输入脚本文件名(不含后缀),这时MATLAB会打开这一脚本文件,并依次执行脚本文件中的每一条语句,这与在MATLAB中直接输入语句的结果完全一致。
(2)函数文件:
它的第一行必须是函数定义行。
函数文件由五部分构成.如文件mean.m为
functiony=mean(x)%函数定义行
%MEANAverageormeanvalue.%H1行.在函数文件的第二行,是帮助文件的第一行
%Forvectors,MEAN(X)isthemeanvalueofX.%此行及下两行为函数帮助文本
%Formatrices,MEAN(X)isarowvector
%containingthemeanvalueofeachcolumn.
%%以下为函数体
[m,n]=size(x);
ifm==1
m=n;
end
y=sum(x)/m
练习:
设x=[134],计算mean(x),分别用短格式、长格式、比式给出结果;
又设x=[1:
3;4:
6],计算mean(x).
答:
>>x=[1,3,4];
>>formatshort
>>mean(x)
ans=2.6667
>>formatlong
>>mean(x)
ans=2.66666666666667
>>formatlonge
>>mean(x)
ans=2.666666666666667e+000
>>formatrat
>>mean(x)
ans=8/3
另
>>x=[1:
3;4:
6];
>>mean(x)
ans=5/27/29/2
我们以这个函数为例来说明函数的各个部分。
1.函数定义行
关键字输出变量=函数名(输入变量)。
当函数具有多个输出变量时,用方括号“[]”括之;
当函数有多个输入变量时,用圆括号“()”括之。
如:
function[x,y,z]=sphere(theta,phi,rho)
当函数不含输出变量时,直接略去输出部分或采用空方括号表示.
如:
functionprintresults(x)或function[]=printresults(x).
所有在函数中使用和生成的变量都为局部变量(除非利用global语句定义),这些变量值只能通过输入和输出变量进行传递。
因此,在调用函数时应通过输入变量将参数传递给函数;函数调用返回时也应通过输出变量将运算结果传递给函数调用者;其它在函数中产生的变量在返回时被全部清除。
2.H1行
在脚本和函数文件中,以“%”开头的行称为注释行,即%之后的字符不被MATLAB执行。
H1行常在函数文件的第二行,这实际上是帮助文件的第一行。
此行不仅可以由helpfunction_name命令显示,而且,lookfor命令只在H1内搜索(且搜索所有H1中有所给内容的文件,非常慢),因此这一行内容提供了这个函数的重要信息。
3.函数帮助文本
这部分内容是以%开头的帮助文本,它用来比较详细地说明这一函数。
当在MATLAB下输入
helpfunction_name时,可显示出H1行和函数帮助文本。
这部分文本从H1行开始,到第一个非%开头的行结束。
4.函数体
函数体是完成指定功能的语句实体,它可采用任何可用的MATLAB命令,包括MATLAB提供的函数和用户自己设计的M函数。
5.注释
注释行是以“%”开头的行,它可出现在函数的任意位置,也可以加在语句行之后,以便对本行进行注释。
在函数文件中,除了函数定义行和函数体之外,其它部分可省略。
4.1.2.脚本文件和函数文件比较
脚本文件和函数文件之间有一些本质上的差异,如表4.1所示。
脚本文件
函数文件
定义行
无需定义行
必须有定义行
输入/输出变量
无
有
数据传送
直接访问基本工作空间中的所有变量
通过输入变量获得输入数据;
通过输出变量提交结果
编程方法
直接选取MATLAB中执行的语句
精心设计完成指定功能
用途
重复操作
MATLAB功能扩展
函数文件去掉其第一行的定义行,变转变成了脚本文件。
但这样一来,原先在函数内使用的局部变量就成了基本工作空间中的变量,这会带来几个问题:
。
基本工作空间中与脚本文件中同名的变量会引起冲突;
。
使基本工作间中的变量数量急剧增加,造成内存紧张;
。
编程时要细心考虑各个脚本文件所用到的变量。
这些问题在函数文件中不复存在,MATLAB通过参与形参一一对应的方式来实现函数的调用,这极大地方便了程序设计。
例如,在编辑器中分别编制出求取平均值与标准差的脚本文件stat1.m和函数文件stat2.m:
stat1.m
%脚本文件
%求阵列x的平均值和标准差
%%以下为函数体
[m,n]=size(x);
ifm==1
m=n;
end
s1=sum(x);s2=sum(x.^2);
mean1=s1/m;
stdev=sqrt(s2/m-mean1.^2);
stat2.m
function[mean1,stdev]=stat2(x)%函数文件
%求阵列x的平均值和标准差
%调用格式为
%[mean,stdev]=stat2(x)
[m,n]=size(x);%以下为函数体
ifm==1
m=n;
end
s1=sum(x);s2=sum(x.^2);
mean1=s1/m;
stdev=sqrt(s2/m-mean1.^2);
编写好这两个文件后,我们在MATLAB下来执行这两个文件,从而对脚本文件和函数文件有一个基本的了解
在MATLAB中输入:
clear%清除基本工作空间中的所有变量
x=rand(4,4)+2;%4行4列的元素在(0,1)内的随机矩阵,每个元素再加上2
stat1;%调用脚本文件stat1.m
disp([mean1;stdev])%显示上面运行的结果,也可将此命令放在上面组合命令中。
2.52752.47792.61992.5768%mean1的结果
0.21960.16760.17290.0924%stdev的结果
whos%检查基本工作空间变量情况:
NameSizeBytesClass
m1x18doublearray
mean11x432doublearray
n1x18doublearray
s11x432doublearray
s21x432doublearray
stdev1x432doublearray
x4x4128doublearray
Grandtotalis34elementsusing272bytes
这说明,在脚本文件中产生的所有变量都返回到了基本工作空间。
再在MATLAB中输入:
clearmns1s2mean1stdev%清除上面执行过的x以外的变量以便观察本程序工
%作空间的变量
[m1,st]=stat2(x);
disp([m1;st])
m1=
2.78862.41912.44032.5133
st=
0.16390.32580.37210.2791
whos%检查基本工作空间变量情况:
NameSizeBytesClass
m11x432doublearray
st1x432doublearray
x4x4128doublearray
Grandtotalis24elementsusing192bytes
这说明,在基本工作空间中,除了原本产生的x矩阵,调用函数stat2.m后,只增加了由函数返回的结果。
通过disp([m1;st])可检查到与stat1.m相同的结果。
4.1.3函数工作空间
每个M文件的函数都有一块用作为工作空间的存贮区域,它与MATLAB的基本工作空间不同,这块区域称为函数工作空间。
每个函数都有自己的工作空间,其中保存着在函数使用的局部变量。
在调用函数时,只有把输入变量传递给函数的变量值,才能在函数中使用,它们来自于被调用函数所在的基本工作空间或函数工作空间。
同样,函数返回的结果传递给被调用函数所在的基本工作空间或函数工作空间。
4.1.4函数变量
在MATLAB函数中,引用的输入/输出变量的数目可少于编写的变量数目,但这时在函数设计中,必须进行适当处理。
在函数中,有两个永久变量nargin和nargout,它们可自动地给出输入变量数和输出变量数,因此利用这两个函数,可根据不同的输入/输出变量数来进行不同的处理。
这在MATAB工具箱的许多函数中都有应用。
例如,编写一个测试函数,要求:
当输入为一个变量时,计算出这一变量的平方;当输入为两个变量时,求出这两个变量的乘积。
我们可以编写函数文件:
functionc=testarg1(a,b)
if(nargin==1)
c=a.^2;
elseif(nargin==2)
c=a*b;
end
运行这个M文件:
>>testarg1
(2)
ans=4
>>testarg1(2,4)
ans=8
又如,在指定字符中找出第一表征字符串的函数,也可使用1个或2个输入变量,输出变量也可为1个或2个。
当输入为1个变量时,则函数使用缺省的分隔符(回车、换行、横向制表符Tab、纵向制表符、行馈、空格)。
当输出变量为2个时,除得到第一表征字符串外,还可得到剩余字符串。
函数文件为(可参见strfun目录中的M文件strtok):
function[token,remainder]=strtok(string,delimiters)
%STRTOKFindtokeninstring.
%STRTOK(S)returnsthefirsttokeninthestringSdelimited
%by"whitespace".Anyleadingwhitespacecharactersareignored.
%
%STRTOK(S,D)returnsthefirsttokendelimitedbyoneofthe
%charactersinD.Anyleadingdelimitercharactersareignored.
%
%[T,R]=STRTOK(...)alsoreturnstheremainderoftheoriginal
%string.
%IfthetokenisnotfoundinSthenRisanemptystringandT
%issameasS.
%
%SeealsoISSPACE.
%Copyright1984-2000TheMathWorks,Inc.
%$Revision:
5.12$$Date:
2000/06/0115:
23:
31$
ifnargin<1,error('Notenoughinputarguments.');end
token=[];remainder=[];
len=length(string);
iflen==0
return
end
if(nargin==1)
delimiters=[9:
1332];%Whitespacecharacters
end
i=1;
while(any(string(i)==delimiters))
i=i+1;
if(i>len),return,end
end
start=i;
while(~any(string(i)==delimiters))
i=i+1;
if(i>len),break,end
end
finish=i-1;
token=string(start:
finish);
if(nargout==2)
remainder=string(finish+1:
length(string));
end
这样,我们在MATLAB下可输入:
>>clear
>>s='Thisisanexample.';
>>[token,rem]=strtok(s)%结果如下
token=This
rem=isanexample.
4.1.5局部变量和全局变量
在函数工作空间中,变量有三类:
。
由调用函数传递输入和输出数据的变量;
。
在函数内部临时产生的变量(局部变量);
。
由调用函数空间、基本工作空间或其它函数工作空间提供的全局变量。
我们曾经提到过,输入数据只能通过输入变量传递。
事实上,有些参数还可以通过将变量宣称为全局变量来传递,而且这时的参数可以来自于函数调用语句所在的函数之外的其它函数。
例如,对于函数:
我们编写出相应的函数文件,其中
采用全局变量进行参数传递。
M函数文件为
functionz=fun1(x,y)%存盘函数名与“fun1”一致,以便调用
globalalphabeta%全局变量宣称
m=length(x);n=length(y);%分别给出向量x与y的长度(元素个数)
x1=x'*ones(1,n);
y1=(y'*ones(1,m))';
z=alpha*(x1-1).^2+beta*(y1+1).^2;
将上面这段程序内容作为文件“fun1.m”存盘,作为调用函数。
下面将用到函数"num2str()",为此,用技巧>>helpnum2str了解它(这个技巧也可用于观察所定函数名是否与内部函数同名,如果同名,可放入到私人函数子目录下,参看4.1.7段)的作用:
接着我们可编写出脚本文件,通过调用函数fun1计算出z,然后利用mesh绘制出网格曲线。
脚本文件为
globalalphabeta
x=[0:
0.2:
2];y=[-2:
0.2:
0];
figure
(1)
subplot(2,2,1),alpha=1;beta=1;
z=fun1(x,y);mesh(z)%如果取消分号“;”,让mesh(z)另起行,
%可得z的列表值,即z的结果。
下同
title(['\alpha=',num2str(alpha),'and\beta=',num2str(beta)])
subplot(2,2,2),alpha=2;beta=1;
z=fun1(x,y);mesh(z)
title(['\alpha=',num2str(alpha),'and\beta=',num2str(beta)])
subplot(2,2,3),alpha=1;beta=2;
z=fun1(x,y);mesh(z)
title(['\alpha=',num2str(alpha),'and\beta=',num2str(beta)])
subplot(2,2,4),alpha=.8;beta=.5;
z=fun1(x,y);mesh(z)
title(['\alpha=',num2str(alpha),'and\beta=',num2str(beta)])
将此脚本文件名存为z.m,接下来可以执行程序:
>>z
即出现下图结果:
这里
通过全局变量传递,因此在函数调用语用z=fun1(x,y)中,每次的x,y都不变,但得到的结果z却不同。
这是因为
已发生了变化。
4.1.6子函数
在函数文件中可以包含多个函数,其中第一个函数称为主函数,其函数名与文件名相同,它可由其它M文件或基本工作空间引用。
在M函数文件中的其它函数称为子函数,它只能由这一个M函数件中的主函数或其它子函数引用。
每个子函数也由函数定义行开始,紧跟其后的语句为函数体。
各种子函数的次序任意,但主函数必须是第一个函数。
例如,我们编写一个求均值和中值的函数memval.m,它包含了两个子函数:
function[avg,med]=mmval(u)%主函数
%NEWSTATSFindmeanandemdianwithinternalfunctions.
n=length(u);%n表示向量u的维数
avg=mean(u,n);
med=median(u,n);%u的中值
functiona=mean(v,n)%子函数
%Calculatemedian.
w=sort(v);
iftem(n,2)==1%tem这个函数待查错?
m=w((n+1)/2);
else
m=(w(n/2)+w(n/2+1))/2;
end
在同一个M文件内的子函数,也只能访问由输入/输出变量传递的变量值、宣称为全局变量的变量值和函数内部的局部变量,这一点与主函数相同。
当在M文件中调用另一个函数时,MATLAB首先在该文件内检查是否为了函数,然后检查是否为私人函数,最后在搜索路径上检查标准的M文件。
由于首先检查的是子函数,因此可使用与已有M文件同名的子函数。
如上例中的mean,虽然存在mean.m函数,但在调用mmval函数时,不会调用mean.m文件,而只执行mmval.m中的子函数mean。
但应注意,在同一个M文件中,函数名应该唯一。
4.1.7私人函数
私人函数是指存放在private子目录中的函数,这些函数只能由其父目录中的函数调用,
而且在函数调用搜索时,它优先于其它MATLAB路径上的函数。
因此每个用户可在自己的private目录中设计或复制并修改一些自己专用的函数,这样可在private中保存修改过的标准函数,以达到特定的效果。
与此同时,其它人使用时仍可采用标准的函数。
4.2流程控制
流程控制语句可改变程序执行的流程,MATLAB的流程控制语句有四类:
。
if,else,elseif,end构成条件转移语句;
。
switch,case,otherwise,end构成情况切换语句;
。
while,end构成不定次重复的循环语句;
。
for,end构成指定次重复的循环语句。
这些语句的使用,给MATLAB程序设计带来了极大的方便,也给设计带来了灵活性。
4.2.1条件语句
最简单的条件语句是仅由if和end组成的语句,它可根据逻辑表达式的值选择是否执行。
例如:
ifrem(a,2)=0
disp('aiseven')
b=a/2;
end
这一段程序完成:
当a为偶数时,b=a/2;否则不作任何处理。
if语句可嵌套使用,多层嵌套可完成复杂的设计任务。
当逻辑表达式不是标量时,则只有当矩阵的所有值为非零时,条件才满足,因此如果X为矩阵,则
ifX
statements
end
等效于
ifall(X(:
))
statements
end
利用else和elseif可进一步给出条件,从而构成复杂的条件语句。
else表示当前面的if(也可能是elseif)表达式为0或FALSES时,执行与之相关联的语句;elseif语句表示当前面的计if或elseif为0或FALSE时,计算本语句的表达式,当表达式为非零或TRUE时,执行与之相关联的语句。
注意在同一个if块中,可含多个elseif语句。
例如,针对输入n的情况,分别进行处理:
4.2.1条件语句
最简单的条件语句是公由if和end组成,它可根据逻辑表达式的值选择是否执行。
如:
(1)
functionz=ex1(a)
ifrem(a,2)==0
disp('aiseven')
b=a/2
end
将这一段程序取名为ex1.m保存在适当路径下,然后运行:
>>a=4;
>>ex1(a)
结果为:
>>a=4;
>>ex1(a)
aiseven
b=2
当a为偶数时,b=a/2;否则不作任何处理。
(2)表达式不是标量时,则只有当矩阵的所有值为非零时,条件才满足,因此如果X为矩阵,则
ifX
statements
end
等效于
ifall(X(:
))
statements
end
(3)利用else和lseif可进一步给出条件,从而构成复杂的条件语句。
Else表示当前面的if(也可能是elseif)表达式为0或FALSE时,执行与之相关联的语句;eseif语句表示前面的if或lseif为0或FALSE时,计算本语句的表达式,当表达式为非零或TRUE时,执行与之相关联的语句。
注意在同一个if块中,可含有多个elseif语句。
例如,针对输入n的情况,分别进行处理:
functionz=ex2(n)
ifn<0
disp('Inputnmustbepositive.')
elseifn==0
disp('n=0')
elseifrem(n,2)==0
disp('n是2的倍数')
elseifrem(n,3)==0
disp('n是3的倍数')
else
disp('其它情况')
end
如:
>>n=-3;
>>ex2(n)
Inputnmustbepositive.
>>n=3;
>>ex2(n)
n是3的倍数
>>n=5;
>>ex2(n)
其它情况
(4)当逻辑表达式为空阵列时,则表示FALSE,例如,当A为空阵列,则语句:
ifA
statemetns1
else
statements2
end
执行statements2.
4.2.2情况切换语句
switch语句可根据表达式的不同取值执行不同的语句,这相当于多条if语句的嵌套使用。
例如,根据var1变量的取值{-1,0,1},分别执行相应的语句,可输入:
functionz=ex4221(var1)
switchvar1
case-1
disp('var1isnegativeone.')
case0
disp('var1iszero.')
case1
disp('var1ispositiveone.')
otherwise
disp('var1isothervalue.')
end
将上述内容以文件ex4221.m存于路径下,则在MATLAB下有:
>>var1=-1;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Matlab 程序设计
![提示](https://static.bdocx.com/images/bang_tan.gif)