第5章MATLAB程序设计Word格式.docx
《第5章MATLAB程序设计Word格式.docx》由会员分享,可在线阅读,更多相关《第5章MATLAB程序设计Word格式.docx(36页珍藏版)》请在冰豆网上搜索。
二阶系统时域响应曲线
zeta阻尼系数
y时域响应
lookfor'
二阶系统时域响应'
Ex0502.m:
%二阶系统时域响应
5.1.3M脚本文件
脚本文件的特点:
(1)脚本文件中的命令格式和前后位置,与在命令窗口中输入的没有任何区别。
(2)MATLAB在运行脚本文件时,只是简单地按顺序从文件中读取一条条命令,送到MATLAB命令窗口中去执行。
(3)与在命令窗口中直接运行命令一样,脚本文件运行产生的变量都是驻留在MATLAB的工作空间(workspace)中,可以很方便地查看变量,除非用clear命令清除;
脚本文件的命令也可以访问工作空间的所有数据,因此要注意避免变量的覆盖而造成程序出错。
【例5.1续】在M文件编辑/调试器窗口中编写M脚本文件绘制二阶系统的多条时域曲线。
(1)单击MATLAB桌面上的
图标打开M文件编辑器。
(2)将命令全部写入M文件编辑器中,为了能标志该文件的名称,在第一行写入包含文件名的注释。
保存文件为Ex0501.m。
)%画阻尼系数为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函数文件
函数文件的特点:
(1)第一行总是以“function”引导的函数声明行;
函数声明行的格式:
function[输出变量列表]=函数名(输入变量列表)
(2)函数文件在运行过程中产生的变量都存放在函数本身的工作空间;
(3)当文件执行完最后一条命令或遇到“return”命令时,就结束函数文件的运行,同时函数工作空间的变量就被清除;
(4)函数的工作空间随具体的M函数文件调用而产生,随调用结束而删除,是独立的、临时的,在MATLAB运行过程中可以产生任意多个临时的函数空间。
【例5.2续】在M文件编辑/调试器窗口编写计算二阶系统时域响应的M函数文件,并在MATLAB命令窗口中调用该文件。
创建M函数文件并调用的步骤如下:
(1)编写函数代码
%EX0502画二阶系统时域曲线
(2)将函数文件保存为“Ex0502.m”。
(3)在MATLAB命令窗口输入以下命令,则会出现f的计算值和绘制的曲线:
f=Ex0502(0.3)
程序分析:
▪第一行指定该文件是函数文件,文件名为“Ex0502”,输入参数为阻尼系数zeta,输出参数为时域响应y。
▪当函数文件调用结束,查看x、y:
x
?
Undefinedfunctionorvariable'
x'
.
y
y'
注意:
M脚本文件和M函数文件的文件名及函数名的命名规则与MATLAB变量的命名规则相同。
5.2程序流程控制
5.2.1for...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:
100,循环次数为向量的列数,每次循环n取一个元素。
【例5.4】使用for...end循环的array矩阵编程将单位阵转换为列向量。
%EX0504使用矩阵for循环
sum=zeros(6,1);
forn=eye(6,6)
sum
1
1
循环变量n对应为矩阵eye(6,6)的每一列,即第一次n为[1;
0;
0],第一次n为[0;
1;
0];
循环次数为矩阵的列数6。
5.2.2while...end循环结构
while表达式
只要表达式为逻辑真,就执行循环体;
一旦表达式为假,就结束循环。
表达式可以是向量也可以是矩阵,如果表达式为矩阵则当所有的元素都为真才执行循环体,如果表达式为nan,MATLAB认为是假,不执行循环体。
【例5.5】与【例5.3】相同,计算1+3+5...+100的值。
%EX0505使用while循环
n=1;
whilen<
=100
n=n+2;
sum
n
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<
zeta<
1和zeta=1两种情况,得出不同的时域响应表达式。
functiony=Ex0506(zeta)
%EX0506使用if结构的二阶系统时域响应
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);
5.2.4switch…case开关结构
switch开关表达式
case表达式1
语句段1
case表达式2
...
otherwise
语句段n
(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}
summer'
case{9,10,11}
autumn'
otherwise
winter'
end
end
season=
winter
spring
summer
autumn
winter
开关表达式为向量1:
12,case后面的表达式为元胞数组,当元胞数组的某个元素与开关表达式相等,就执行其后的语句段。
5.2.5try...catch...end试探结构
try
语句段1
catch
首先试探性地执行语句段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
lasterr
c=
1623
51110
976
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循环
ifsum<
1000
n=n+2;
else
break
1024
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:
form=2:
fix(sqrt(n))
ifmod(n,m)==0
ss=1;
%能被整除就用ss为1表示
break;
%能被整除就跳出内循环
ss=0;
%不能被整除就用ss为0表示
ifss==1
continue;
%能被整除就跳出本次外循环
end
end
1060
fix(sqrt(n))是将
取整;
本程序为双重循环,两个for循环嵌套还嵌套一个if结构;
当mod(n,m)==0时就用break跳出判断是否为素数的内循环,并继续用continue跳出求素数和的外循环而继续下次外循环。
3.return命令
return命令是终止当前命令的执行,并且立即返回到上一级调用函数或等待键盘输入命令,可以用来提前结束程序的运行。
当程序进入死循环,则按Ctrl+break键来终止程序的运行。
4.pause命令
pause命令用来使程序运行暂停,等待用户按任意键继续。
pause%暂停
pause(n)%暂停n秒
5.keyboard命令
keyboard命令用来使程序暂停运行,等待键盘命令,执行完自己的工作后,输入return语句,程序就继续运行。
6.input命令
input命令用来提示用户应该从键盘输入数值、字符串和表达式,并接受该输入。
a=input('
inputanumber:
'
)%输入数值给a
45
a=
45
b=input('
'
s'
)%输入字符串给b
b=
input('
)%将输入值进行运算
2+3
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
z1=0.5
Ex0502(z1)%调用Ex0502
z1=0.707;
%子函数,画二阶系统时域曲线
主函数是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:
z1=0.5;
functionEx0502(zeta)
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函数的参数
1.参数传递规则
【例5.13】将【例5.11】画二阶系统时域的函数修改,使用输入输出参数来实现参数传递,如图5.3所示。
主函数Ex0513调用子函数Ex0502,子函数中的zeta为输入参数,函数调用时将z1传递给子函数zeta,子函数计算后将输出参数x和y传回给主函数的x1、y1;
主函数调用子函数三次,后面两次参数的传递也是同样。
2.函数参数的个数
(1)nargin和nargout变量
函数的输入输出参数的个数可以通过变量nargin和nargout获得,nargin用于获得输入参数的个数,nargout用于获得输出参数的个数。
nargin%在函数体内获取实际输入变量的个数
nargout%在函数体内获取实际输出变量的个数
nargin(’fun’)%在函数体外获取定义的输入参数个数
nargout(‘fun’)%在函数体外获取定义的输出参数个数
【例5.14】计算两个数的和,根据输入的参数个数不同使用不同的运算表达式。
function[sum,n]=Ex0514(x,y)
%EX0514参数个数可变,计算x和y的和
ifnargin==1
sum=x+0;
%输入一个参数就计算与0的和
elseifnargin==0
sum=0;
%无输入参数就输出0
else
sum=x+y;
%输入的是两个数则就计算和
在命令窗口调用Ex0514函数,分别使用2个、1个和无输入参数结果如下:
[y,n]=Ex0514(2,3)
y=
2
[y,n]=Ex0514
(2)
2
[y,n]=Ex0514
0
0
如果输入的参数多于输入参数个数,则会出错。
[y,n]=Ex0514(1,2,3)
Errorusing==>
ex0514
Toomanyinputarguments.
也可以在工作空间查看函数体定义的输入参数个数:
nargin('
Ex0514'
)
【例5.14续】添加以下程序,查看用nargout变量获取输出参数个数。
ifnargout==0%当输出参数个数为0时,运算结果为0
在命令窗口调用Ex0514函数,当输出参数格式不同时,结果如下:
Ex0514(2,3)%当输出参数个数为0时
y=Ex0514(2,3)%当输出参数个数为1时
5
[y,n,x]=Ex0514%当输出参数个数为太多时
Toomanyoutputarguments.
当输出参数个数为0时,即使有两个输入参数,运算结果也为0,结果送给ans变量;
当输出的参数个数太多,也会出错。
(2)varargin和varargout变量
varargin和varargout可以获得输入输出变量的