第5章MATLAB程序设计.docx
- 文档编号:24583098
- 上传时间:2023-05-29
- 格式:DOCX
- 页数:29
- 大小:206.06KB
第5章MATLAB程序设计.docx
《第5章MATLAB程序设计.docx》由会员分享,可在线阅读,更多相关《第5章MATLAB程序设计.docx(29页珍藏版)》请在冰豆网上搜索。
第5章MATLAB程序设计
第5章MATLAB程序设计
MATLAB除了可以在命令窗口中编写行命令外,作为一种高级应用软件还可以生成自己的程序文件。
5.1脚本文件和函数文件
MATLAB程序代码所编写的文件通常以“.m”为扩展名,因此这些文件称为M文件。
M文件是一个ASCII码文件,可以用任何文本处理软件来编写,M文件在第一次运行时由于逐句解释运行程序,故速度比编译型的慢,单M文件一经运行就将编译代码放在内存中,再次运行的速度就大大加快。
M文件有两种形式:
M脚本文件和M函数文件。
M函数文件是MATLAB程序设计的主流,一系列工具箱的内部函数都是M函数文件。
5.1.1M文本编辑器
MATLAB的M文件是通过M文件编辑/调试器窗口(Editor/Debugger)来创建的。
单击MATLAB桌面上的
图标,或者单击菜单“File”——“New”——“M-file”,可打开空白的M文件编辑器,也可以通过打开已有的M文件来打开M文件编辑器。
如图5.1所示为打开已创建的M文件。
5.1.2M文件的基本格式
M脚本文件和M函数文件的格式不同。
下面介绍绘制二阶系统时域曲线的M文件,欠阻尼系统的时域输出y与x的关系为
,【例5.1】为M脚本文件,【例5.2】为M函数文件。
【例5.1】用M脚本文件绘制二阶系统时域曲线。
%EX0501二阶系统时域曲线
%画阻尼系数为0.3的曲线
x=0:
0.1:
20;
y1=1-1/sqrt(1-0.3^2)*exp(-0.3*x).*sin(sqrt(1-0.3^2)*x+a
cos(0.3))
plot(x,y1,'r')
【例5.2】创建一个画二阶系统时域曲线的函数,阻尼系数zeta为函数的输入参数。
functiony=Ex0502(zeta)
%EX0502Stepresponseofquadraticsystem.
%二阶系统时域响应曲线
%zeta阻尼系数
%y时域响应
%
%copyright2003-08-01
x=0:
0.1:
20;
y=1-1/sqrt(1-zeta^2)*exp(-zeta*x).*sin(sqrt(1-zeta^2)*x+acos(zeta))
plot(x,y)
M函数文件的基本格式:
函数声明行
H1行(用%开头的注释行)
在线帮助文本(用%开头)
编写和修改记录(用%开头)
函数体
说明:
1)函数声明行是M函数所必须的,M脚本文件没有函数声明;函数名与文件名保持一致,当不一致时,MATLAB以文件名为准,上例中,Ex0502函数保存为Ex0502.m文件。
2)H1行通常包含大写的函数文件名,可以提供给help和lookfor关键词使用。
3)在线帮助文本通常包含函数输入、输出变量的含义、格式说明。
4)编写和修改记录一般在空1行后,记录作者、日期和版本记录,用于软件档案管理。
例如,在命令窗口输入help和lookfor命令查看帮助信息:
helpEx0502
EX0502Stepresponseofquadraticsystem.
二阶系统时域响应曲线
zeta阻尼系数
y时域响应
lookfor'二阶系统时域响应'
Ex0502.m:
%二阶系统时域响应
Help命令显示M文件的第一个连续注释块,lookfor命令显示第一行注释。
函数体由实现M函数文件功能的MATLAB命令组成。
5.1.3M脚本文件(ScriptFile)
脚本文件(命令文件):
实际上是一串指令的集合,与在命令窗口逐行执行文件中的所有指令,其结果是一样的。
没有输入输出参数。
脚本文件的特点:
(1)脚本文件中的命令格式和前后位置,与在命令窗口中输入的没有任何区别。
(2)MATLAB在运行脚本文件时,只是简单地按顺序从文件中读取一条条命令,送到MATLAB命令窗口中去执行。
(3)与在命令窗口中直接运行命令一样,脚本文件运行产生的变量都是驻留在MATLAB的工作空间(workspace)中,可以很方便地查看变量,除非用clear命令清除;脚本文件的命令也可以访问工作空间的所有数据,因此要注意避免变量的覆盖而造成程序出错。
【例5.1续】在M文件编辑/调试器窗口中编写M脚本文件绘制二阶系统的多条时域曲线。
(1)单击MATLAB桌面上的
图标打开M文件编辑器。
(2)将命令全部写入M文件编辑器中,为了能标志该文件的名称,在第一行写入包含文件名的注释。
保存文件为Ex0501.m。
%EX0501二阶系统时域曲线
x=0:
0.1:
20;
y1=1-1/sqrt(1-0.3^2)*exp(-0.3*x).*sin(sqrt(1-0.3^2)*x+acos(0.3))
plot(x,y1,'r')%画阻尼系数为0.3的曲线
holdon
y2=1-1/sqrt(1-0.707^2)*exp(-0.707*x).*sin(sqrt(1-0.707^2)*x+acos(0.707))
plot(x,y2,'g')%画阻尼系数为0.707的曲线
y3=1-exp(-x).*(1+x)
plot(x,y3,'b')%画阻尼系数为1的曲线
(3)选择M文件编辑器菜单“Debug”——“Run”,就可以在图形窗中看到如图5.2所示的曲线。
查看工作空间的变量:
whos
NameSizeBytesClass
x1x2011608doublearray
y11x2011608doublearray
y21x2011608doublearray
y31x2011608doublearray
Grandtotalis804elementsusing6432bytes
5.1.4M函数文件(FunctionFile)
函数文件:
组成的文件构成一个函数,需要输入变量,返回输出变量。
函数文件的特点:
(1)第一行总是以“function”引导的函数声明行;
函数声明行的格式:
function[输出变量列表]=函数名(输入变量列表)
(2)函数文件在运行过程中产生的变量都存放在函数本身的工作空间;
(3)当文件执行完最后一条命令或遇到“return”命令时,就结束函数文件的运行,同时函数工作空间的变量就被清除;
(4)函数的工作空间随具体的M函数文件调用而产生,随调用结束而删除,是独立的、临时的,在MATLAB运行过程中可以产生任意多个临时的函数空间。
【例5.2续】在M文件编辑/调试器窗口编写计算二阶系统时域响应的M函数文件,并在MATLAB命令窗口中调用该文件。
创建M函数文件并调用的步骤如下:
(1)编写函数代码
functiony=Ex0502(zeta)
%EX0502画二阶系统时域曲线
x=0:
0.1:
20;
y=1-1/sqrt(1-zeta^2)*exp(-zeta*x).*sin(sqrt(1-zeta^2)*x+acos(zeta))
plot(x,y)
(2)将函数文件保存为“Ex0502.m”。
(3)在MATLAB命令窗口输入以下命令,则会出现f的计算值和绘制的曲线:
f=Ex0502(0.3)
程序分析:
▪第一行指定该文件是函数文件,文件名为“Ex0502”,输入参数为阻尼系数zeta,输出参数为时域响应y。
▪当函数文件调用结束,查看x、y:
x
?
?
?
Undefinedfunctionorvariable'x'.
y
?
?
?
Undefinedfunctionorvariable'y'.
注意:
M脚本文件和M函数文件的文件名及函数名的命名规则与MATLAB变量的命名规则相同。
5.2程序流程控制
5.2.1for...end循环结构
循环结构有两种:
for…end结构和while…end结构。
这两种结构不完全相同,各有特点。
语法:
for循环变量=array
循环体
end
说明:
循环体被循环执行,执行的次数就是array的列数,array可以是向量也可以是矩阵,循环变量依次取array的各列,每取一次循环体执行一次。
【例5.3】使用for...end循环的array向量编程求出1+3+5...+100的值。
%EX0503使用向量for循环
sum=0;
forn=1:
2:
100
sum=sum+n;
end
sum
sum=
2500
计算的结果为:
sum=2500。
程序说明:
循环变量为n,n对应为向量1:
2:
100,循环次数为向量的列数,每次循环n取一个元素。
【例5.4】使用for...end循环的array矩阵编程将单位阵转换为列向量。
%EX0504使用矩阵for循环
sum=zeros(6,1);
forn=eye(6,6)
sum=sum+n;
end
sum
sum=
1
1
1
1
1
1
程序分析:
循环变量n对应为矩阵eye(6,6)的每一列,即第一次n为[1;0;0;0;0;0],第二次n为[0;1;0;0;0;0];循环次数为矩阵的列数6。
5.2.2while...end循环结构
语法:
while表达式
循环体
end
说明:
只要表达式为逻辑真,就执行循环体;一旦表达式为假,就结束循环。
表达式可以是向量也可以是矩阵,如果表达式为矩阵则当所有的元素都为真才执行循环体,如果表达式为nan,MATLAB认为是假,不执行循环体。
【例5.5】与【例5.3】相同,计算1+3+5...+100的值。
%EX0505使用while循环
sum=0;
n=1;
whilen<=100
sum=sum+n;
n=n+2;
end
sum
n
sum=
2500
n=
101
程序分析:
可以看出while...end循环的循环次数由表达式来决定,当n=101就停止循环。
5.2.3If…else…end条件转移结构
语法:
if条件式1
语句段1
elseif条件式2
语句段2
...
else
语句段n+1
end
说明:
当有多个条件时,条件式1为假再判断elseif的条件式2,如果所有的条件式都不满足,则执行else的语句段n+1,当条件式为真则执行相应的语句段;If…else…end结构也可以是没有elseif和else的简单结构。
【例5.6】用If结构执行二阶系统时域响应,根据阻尼系数0 functiony=Ex0506(zeta) %EX0506使用if结构的二阶系统时域响应 x=0: 0.1: 20; if(zeta>0)&(zeta<1) y=1-1/sqrt(1-zeta^2)*exp(-zeta*x).*sin(sqrt(1-zeta^2)*x+acos(zeta)); elseifzeta==1 y=1-exp(-x).*(1+x); end plot(x,y) 5.2.4switch…case开关结构 语法: switch开关表达式 case表达式1 语句段1 case表达式2 语句段2 ... otherwise 语句段n end 说明: (1)将开关表达式依次与case后面的表达式进行比较,如果表达式1不满足,则与下一个表达式2比较,如果都不满足则执行otherwise后面的语句段n;一旦开关表达式与某个表达式相等,则执行其后面的语句段。 (2)开关表达式只能是标量或字符串。 (3)case后面的表达式可以是标量、字符串或元胞数组,如果是元胞数组则将开关表达式与元胞数组的所有元素进行比较,只要某个元素与开关表达式相等,就执行其后的语句段。 【例5.7】用switch…case开关结构得出各月份的季节。 %EX0507使用switch结构 formonth=1: 12; switchmonth case{3,4,5} season='spring' case{6,7,8} season='summer' case{9,10,11} season='autumn' otherwise season='winter' end end season= winter season= winter season= spring season= spring season= spring season= summer season= summer season= summer season= autumn season= autumn season= autumn season= winter 程序分析: 开关表达式为向量1: 12,case后面的表达式为元胞数组,当元胞数组的某个元素与开关表达式相等,就执行其后的语句段。 5.2.5try...catch...end试探结构 语法: try 语句段1 catch 语句段2 end 说明: 首先试探性地执行语句段1,如果在此段语句执行过程中出现错误,则将错误信息赋给保留的lasterr变量,并放弃这段语句,转而执行语句段2中的语句,当执行语句段2又出现错误,则终止该结构。 【例5.8】用try...catch...end结构来进行矩阵相乘运算。 %EX0508try结构 n=4; a=magic(n); m=3; b=eye(3); try c=a*b catch c=a(1: m,1: m)*b end lasterr 计算结果是: c= 1623 51110 976 用lasterr函数查看出错的原因显示为: ans= Errorusing==>* Innermatrixdimensionsmustagree. 程序分析: 试探出矩阵的大小不匹配时,矩阵无法相乘,则再执行catch后面的语句段,将a的子矩阵取出与b矩阵相乘。 可以通过这种结构灵活地实现矩阵的乘法运算。 5.2.6流程控制语句 1.break命令 break命令可以使包含break的最内层的for或while语句强制终止,立即跳出该结构,执行end后面的命令,break命令一般和If结构结合使用。 【例5.9】将【例5.5】增加条件用If与break命令结合,停止while循环。 计算1+3+5...+100的值,当和大于1000时终止计算。 %EX0509用break终止while循环 sum=0; n=1; whilen<=100 ifsum<1000 sum=sum+n; n=n+2; else break end end sum n sum= 1024 n= 65 程序分析: while…end循环结构嵌套If…else…end分支结构,当sum为1024时跳出while循环结构,终止循环。 2.continue命令 continue命令用于结束本次for或while循环,只结束本次循环而继续进行下次循环。 【例5.10】将If命令与continue命令结合,计算的1~100中所有素数的和,判断是否为素数是将100以内的每个数都被2~ 整除,不能被整除的就是素数。 %EX0510用continue终止while循环 sum=2;ss=0; forn=3: 100 form=2: fix(sqrt(n)) ifmod(n,m)==0 ss=1; %能被整除就用ss为1表示 break; %能被整除就跳出内循环 else ss=0; %不能被整除就用ss为0表示 end end ifss==1 continue; %能被整除就跳出本次外循环 end sum=sum+n; end sum sum= 1060 程序分析: fix(sqrt(n))是将 取整;本程序为双重循环,两个for循环嵌套还嵌套一个if结构;当mod(n,m)==0时就用break跳出判断是否为素数的内循环,并继续用continue跳出求素数和的外循环而继续下次外循环。 3.return命令 return命令是终止当前命令的执行,并且立即返回到上一级调用函数或等待键盘输入命令,可以用来提前结束程序的运行。 Exa.functiond=det(A) ifisempty(A) d=1; return else ... end 注意: 当程序进入死循环,则按Ctrl+break键来终止程序的运行。 4.pause命令 pause命令用来使程序运行暂停,等待用户按任意键继续。 语法: pause%暂停 pause(n)%暂停n秒 5.keyboard命令 keyboard命令用来使程序暂停运行,等待键盘命令,执行完自己的工作后,输入return语句,程序就继续运行。 6.input命令 input命令用来提示用户应该从键盘输入数值、字符串和表达式,并接受该输入。 a=input('inputanumber: ') %输入数值给a inputanumber: 45 a= 45 b=input('inputanumber: ','s') %输入字符串给b inputanumber: 45 b= 45 input('inputanumber: ') %将输入值进行运算 inputanumber: 2+3 ans= 5 5.3函数调用和参数传递 5.3.1子函数和私有函数 1.子函数 在一个M函数文件中,可以包含一个以上的函数,其中只有一个是主函数,其它则为子函数。 (1)在一个M文件中,主函数必须出现在最上方,其后是子函数,子函数的次序无任何限制; (2)子函数不能被其它文件的函数调用,只能被同一文件中的函数(可以是主函数或子函数)调用; (3)同一文件的主函数和子函数变量的工作空间相互独立; (4)用help和lookfor命令不能提供子函数的帮助信息。 【例5.11】将【例5.2】画二阶系统时域曲线的函数作为子函数,编写画多条曲线的程序。 functionEx0511() %EX0511使用函数调用绘制二阶系统时域响应 z1=0.3; Ex0502(z1);%调用Ex0502 holdon z1=0.5 Ex0502(z1)%调用Ex0502 z1=0.707; Ex0502(z1)%调用Ex0502 functiony=Ex0502(zeta) %子函数,画二阶系统时域曲线 x=0: 0.1: 20; y=1-1/sqrt(1-zeta^2)*exp(-zeta*x).*sin(sqrt(1-zeta^2)*x+acos(zeta)) plot(x,y) 程序分析: 主函数是Ex0511,子函数是Ex0502,在主函数中三次调用子函数。 程序保存为Ex0511.m文件。 2.私有函数 私有函数是指存放在private子目录中的M函数文件,具有以下性质: (1)在private目录下的私有函数,只能被其父目录的M函数文件所调用,而不能被其它目录的函数调用,对其它目录的文件私有函数是不可见的,私有函数可以和其它目录下的函数重名; (2)私有函数父目录的M脚本文件也不可调用私有函数; (3)在函数调用搜索时,私有函数优先于其它MATLAB路径上的函数。 3.调用函数的搜索顺序 在MATLAB中调用一个函数,搜索的顺序如下: ▪查找是否子函数; ▪查找是否私有函数; ▪从当前路径中搜索此函数; ▪从搜索路径中搜索此函数。 5.3.2局部变量和全局变量 1.局部变量 局部变量(LocalVariables)是在函数体内部使用的变量,其影响范围只能在本函数内,只在函数执行期间存在。 2.全局变量 全局变量(GlobalVariables)是可以在不同的函数工作空间和MATALB工作空间中共享使用的变量。 【例5.12】修改【例5.11】在主函数和子函数中使用全局变量。 functionEx0512() %EX0512使用全局变量绘制二阶系统时域响应 globalX X=0: 0.1: 20; z1=0.3; Ex0502(z1); holdon z1=0.5; Ex0502(z1); z1=0.707; Ex0502(z1); functionEx0502(zeta) %子函数,画二阶系统时域曲线 globalX y=1-1/sqrt(1-zeta^2)*exp(-zeta*X).*sin(sqrt(1-zeta^2)*X+acos(zeta)); plot(X,y); 程序分析: X变量为全局变量,在需要使用的主函数和子函数中都需要用global定义;同样如果在工作空间中定义X为全局变量后也可以使用: globalX who Yourvariablesare: X 注意: 由于全局变量在任何定义过的函数中都可以修改,因此不提倡使用全局变量;必须使用时应十分小心,建议把全局变量的定义放在函数体的开始,全局变量用大写字符命名。 5.3.3函数的参数 MATLAB的函数调用过程实际上就是参数参数传递的过程。 参数调用的格式: [输出参数1,输出参数2,…]= 函数名(输入参数1,输入参数2,…) 1.参数传递规则 在MATLAB中,函数具有自己的工作空间,函数内变量与外界(包括其他函数和工作空间)的唯一联系就是通过函数的输入、输出参数。 输入参数在函数中的任何变化,都仅在函数内进行,不会传递回去。 【例5.13】将【例5.11】画二阶系统时域的函数修改,使用输入输出参数来实现参数传递,如图5.3所示。 程序分析: 主函数Ex0513调用子函数Ex0502,子函数中的zeta为输入参数,函数调用时将z1传递给子函数zeta,子函数计算后将输出参数x和y传回给主函数的x1、y1;主函数调用子函数三次,后面两次参数的传递也是同样。 2.函数参数的个数 MATLAB函数的调用有一个与其他语言不同的特点是: 函数的输入、输出参数的数目都可以变化,用户可以根据参数的个数来编程。 (1)nargin和nargout变量 函数的输入输出参数的个数可以通过变量nargin和nargout获得,nargin用于获得输入参数的个数,nargout用于获得输出参数的个数。 语法: nargin%在函数体内
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第5章 MATLAB程序设计 MATLAB 程序设计