第七章 m 文件和面向对象编程

57
第第第 M 第第第第第第第第第 第第 第第 第第第第第第第第第第 第第第第第第第 第第第第 第第 第第第 第 (、); 第第第第第 第第第第第第 第第

Upload: asabi

Post on 16-Mar-2016

130 views

Category:

Documents


0 download

DESCRIPTION

第七章 M 文件和面向对象编程. 内容:. 脚本; 函数; 函数句柄的创建和使用; 程序调试和剖析; 数据结构(类、对象); 重载和继承; 面向对象编程. 7.1 入门. 通过M脚本文件,画出下列分段函数所表示的曲面。. a=2;b=2; clf; x=-a:0.2:a;y=-b:0.2:b; for i=1:length(y) for j=1:length(x) if x(j)+y(i)>1 z(i,j)=0.5457*exp(-0.75*y(i)^2-3.75*x(j)^2-1.5*x(j)); - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第七章  M  文件和面向对象编程

第七章 M 文件和面向对象编程脚本;函数;函数句柄的创建和使用;程序调试和剖析;数据结构(类、对象);重载和继承;面向对象编程

内容:

Page 2: 第七章  M  文件和面向对象编程

7.1 入门

通过M脚本文件,画出下列分段函数所表示的曲面。

15457.0

117575.0

15457.0

),(

215.175.375.0

216

215.175.375.0

21

121

22

21

22

121

22

xxe

xxe

xxe

xxpxxx

xx

xxx

Page 3: 第七章  M  文件和面向对象编程

a=2;b=2; clf;x=-a:0.2:a;y=-b:0.2:b;for i=1:length(y) for j=1:length(x) if x(j)+y(i)>1 z(i,j)=0.5457*exp(-0.75*y(i)^2-3.75*x(j)^2-1.5*x(j)); elseif x(j)+y(i)<=-1 z(i,j)=0.5457*exp(-0.75*y(i)^2-3.75*x(j)^2+1.5*x(j)); else z(i,j)=0.7575*exp(-y(i)^2-6*x(j)^2); end endendaxis([-a,a,-b,b,min(min(z)),max(max(z))]);colormap(flipud(winter));surf(x,y,z);

Page 4: 第七章  M  文件和面向对象编程

7.2 MATLAB 控制流

7.2.1 for 循环结构语法形式:for x=array(commands)end

for i=1:10;x(i)=i;end;

Page 5: 第七章  M  文件和面向对象编程

7.2.2 while 循环结构语法形式:while expression(commands)end

i=1;while i<10;x(i)=i;i=i+1;end;

Page 6: 第七章  M  文件和面向对象编程

a = 0; fa = -Inf;b = 3; fb = Inf;while b-a > eps*b x = (a+b)/2; fx = x^3-2*x-5; if sign(fx) == sign(fa) a = x; fa = fx; else b = x; fb = fx; endendx

Page 7: 第七章  M  文件和面向对象编程

7.2.3 if-else-end分支

( 1 ) if 表达式执行语句end

功能:如果表达式的值为真,就执行语句,否则执行 end 后面的语句。

Page 8: 第七章  M  文件和面向对象编程

( 2 ) if 表达式执行语句 1else执行语句 2end

功能:如果表达式的值为真,就执行语句 1 ,否则执行语句 2 。

Page 9: 第七章  M  文件和面向对象编程

( 3) if 表达式 1执行语句 1 elseif 表达式 2执行语句 2 else语句 n end 功能:如果表达式 1 的值为真,就执行语句 1,然后跳出 if 执行语句;否则判断表达式 2 ,如果表达式 2 的值为真,就执行语句 2 ,然后跳出 if 执行语句 . 否则依此类推,一直进行下去。如果所有的表达式的值都为假,就执行 end 后面的语句。

Page 10: 第七章  M  文件和面向对象编程

7.2.4 switch-case 结构Switch 语句的形式为: switch 表达式 case 常量表达式 1 语句块 1 case 常量表达式 2 语句块 2 case { 常量表达式 n ,常量表达式 n+1 ,… } 语句块 notherwise语句块 n+1end

Page 11: 第七章  M  文件和面向对象编程

功能:switch 语句后面的表达式可以为任何类型;每个 case 后面的常量表达式可以是多个,也可以是不同类型;与 if 语句不同的是,各个 case 和 otherwise 语句出现的先后顺序不会影响程序运行的结果。

Page 12: 第七章  M  文件和面向对象编程

例 : 编一个转换成绩等级的函数文件,其中成绩等级转换标准为考试成绩分数在 [90, 100]分显示优秀;在 [80, 90)分显示良好;在 [60, 80)分显示及格;在 [0, 60)分显示不及格。

Page 13: 第七章  M  文件和面向对象编程

function result=ff(x) n=fix(x/10); switch n case {9,10} disp('优秀 ') case 8 disp('良好 ')case {6,7} disp('及格 ')otherwise disp('不及格 ')end

Page 14: 第七章  M  文件和面向对象编程

语法结构try( commands1 )catch( commands2 )end说明: 只有当 matlab 在执行组命令 1 时出现了错误后,组命令 2 才会被执行 可调用 lasterr 函数查询出错原因 当执行组命令 2 时又出错, matlab 将终止该结构

7.2.5 try-catch 结构

Page 15: 第七章  M  文件和面向对象编程

例 对 (3× 3) 魔方阵的行进行援引,当“行下标”超出魔方阵的最大行数时,将改向对最后一行的援引,并显示“出错”警告。clear,N=4;A=magic(3);tryA_N=A(N,:)catchA_end=A(end,:)endlasterr

Page 16: 第七章  M  文件和面向对象编程

7.2.6 控制程序流的其它常用指令 1 return 指令

通常,当被调函数执行完后, matlab 会自动地把控制转至主调函数或者指令窗。如果在被调函数中插入了 return 指令,可以强制 matlab 结束执行该函数并把控制转出。

Page 17: 第七章  M  文件和面向对象编程

2 input 和 keyboard 指令( 1 ) input

input 指令将 matlab 的“控制权”暂时交给用户。此后,用户通过键盘键入数值、字符串或者表达式,并经“回车”把键入内容输入工作空间,同时把“控制权”交还给matlab 。

Page 18: 第七章  M  文件和面向对象编程

格式:v=input(‘message’) 将用户键入的内容赋给变量 vv=input(‘message’,’s’) 将用户键入的内容作为字符串赋给变量 v说明: 指令中‘ message’ 是将显示在屏幕上的字符串,是必不可少的 对于第一种调用格式,用户可以输入数值、字符串、元胞数组等各种形式的数据。 对于第二种调用格式,不管键入什么,总以字符串形式赋给变量 v 。

Page 19: 第七章  M  文件和面向对象编程

( 2 ) keyboard 指令当程序遇到 keyboard 时, matlab 将“控制权”交给键盘,用户可以从键盘输入各种合法的 matlab 指令,只有当用户使用 return 指令结束输入后,“控制权”才交还给程序。

( 3 ) pause 指令pause 暂停执行文件,等待用户按任意键继续。pause(n) 在继续执行之前,暂停 n 秒

( 4 ) break 指令break 指令可以导致包含有该指令的 while 、 for 等指令终止。

Page 20: 第七章  M  文件和面向对象编程

常用的警示指令: error('message')显示出错信息 message ,终止程序。 errortrap 错误发生后,程序继续执行与否的双位开关。 lasterr 显示 matlab 自动判断的最新出错原因并终止程序。 warning (‘ message’ )显示警告信息 message ,程序继续运行。 lastwarn 显示 matlab 自动给出的最新警告,程序继续运行。

( 5 ) error 和 warning 指令

Page 21: 第七章  M  文件和面向对象编程

7.3 脚本文件和函数文件7.3.1 M 脚本文件M 脚本文件特点: 它只是一串按用户意图排列而成的 matlab 指令集合。 脚本文件运行后,所产生的所有变量都驻留在 matla

b基本工作空间中。

Page 22: 第七章  M  文件和面向对象编程

7.3.2 M 函数文件与脚本文件不同,函数文件犹如一个“黑箱”,它的特点: 从形式上看,与脚本文件不同,函数文件的第一行总是以“ function” 引导的函数申明行。 matlab允许使用比“标称数目”较少的输入输出参数,实现对函数的调用。 从运行上看,中间变量都存在在临时工作空间。 在 matlab整个运行期间,可以产生任意多个临时函数空间。 假如在函数文件中,发生对某脚本文件的调用,那么该脚本文件运行产生的所有变量都存放于函数空间之中,而不是存放在基本空间。

Page 23: 第七章  M  文件和面向对象编程

7.3.3 局部变量和全局变量( 1 )局部( local )变量存在于函数空间内部的中间变量,产生于该函数的运行过程中,其影响范围仅限于该函数本身。

( 2 )全局( Global )变量通过 global 指令, matlab允许几个不同的函数空间以及基本工作空间共享同一个变量,这种被共享的变量称为全局变量。

Page 24: 第七章  M  文件和面向对象编程

说明:没采用 global定义的函数或基本工作空间,将无权享用全局变量。除非与全局变量联系的所有工作空间都被删除,否则全局变量依然存在。 对全局变量的定义必须在该变量被使用之前进行。建议把全局变量的定义放在函数体的首行位置。 建议选用大写字符命名全局变量 不提倡使用全局变量。

Page 25: 第七章  M  文件和面向对象编程

7.3.4 M文件的一般结构演示:( A )编写一个画任意半径任意色彩线型的圆。( B )完整函数文件的基本结构。( C )函数文件各基本组成部分的作用。(参看 lesson7-1)

Page 26: 第七章  M  文件和面向对象编程

M 函数文件的结构如下: 函数申明行 H1 行( The first help text line ) 在线帮助文本( help text )区 编写和修改记录 函数体

Page 27: 第七章  M  文件和面向对象编程

7.3.5 P码文件1 、语法分析过程和伪代码

一个 M 文件首次被调用时, matlab 将首先对该 M文件进行语法分析,并把生成的相应内部伪代码文件存放在内存中。Matlab 的分析器总是把 M 文件连同被它调用的所有函数 M 文件一起变成 P码文件

形式:文件名相同,扩展名是” .p”

Page 28: 第七章  M  文件和面向对象编程

2 、 P码文件的预生成P码文件可以被预先生成pcode FunName 在当前目录上生成 FunName.ppcode FunName -inplace在 FunName.m 所在目录上生成 FunName.p

P码文件的优点: 运行速度快; 程序保密性好;

Page 29: 第七章  M  文件和面向对象编程

3 、内存中 P码文件的列表和清除inmem罗列出内存中所有 P码文件名clear FunName清除内存中的 FunName.pP码文件clear functions清除内存中的所有 P码文件

Page 30: 第七章  M  文件和面向对象编程

7.3.6 Matlab 的搜索过程假设Matlab 在一个文件中碰到指令 cow 时,它将按以下步骤进行检索。( 1 )检查 cow 是否一个变量名;如果不是,执行下一步。( 2 )检查 cow 是不是内建函数( Built-in Function );假如不是,执行下一步。( 3 )检查 cow 是不是 cow 所在的 M 文件中的一个子函数;假如不是,再往下执行。( 4 )检查 cow 是不是 cow 所在的 M 文件中的一个私有函数;假如不是,在往下执行。( 5 )检查 cow 是不是当前目录上的文件;假如不是,再往下执行。( 6 )检查搜索路径上是否有 cow存在。

Page 31: 第七章  M  文件和面向对象编程

7.4 变量的检测传递和限权使用函数7.4.1 输入输出宗量检测指令nargin在函数体内,用于获取实际输入参数nargout在函数体内,用于获取实际输出参数nargin(‘fun’)获取‘ fun’ 指定函数的标称输入参数个数nargout(‘fun’)获取’ fun’ 指定函数的标称输出参数个数inputname(n) 在函数体内使用,给出第 n 个输入参数的实际调用变量名

Page 32: 第七章  M  文件和面向对象编程

7.4.2“ 变长度”输入输出参数varargin “ 变长度”输入参数列表varargout “ 变长度”输出参数列表

例 编写程序,画两个同心圆环,其中一个半径由独立输入参数定义,另一个由变长度输入参数的第一个参数定义,可以用任何指定的色彩,线型绘制;( lesson7_2 )

Page 33: 第七章  M  文件和面向对象编程

有输出情况r1=1;r2=3;[x1,y1,x2,y2,s1,s2]=lesson7_2(r1);[x1,y1,x2,y2]=lesson7_2(r1,r2);[x1,y1,x2,y2,s1,s2]=lesson7_2(r1,r2);

无输出情况r1=1;r2=0.6;subplot(1,3,1),lesson7_2(r1,r2);subplot(1,3,2),lesson7_2(r1,r2,'Marker','o')subplot(1,3,3);lesson7_2(r1,r2,'LineWidth',5,'Color',[1 0.4 0])

Page 34: 第七章  M  文件和面向对象编程

7.4.3 跨空间变量传递1 、 跨空间计算串表达式的值evalin(‘workspace’,’expression’)跨空间计算表达式值evalin(‘workspace’,’expression1’,’expression2’)跨空间计算替代串表达式值

Page 35: 第七章  M  文件和面向对象编程

例 编写绘制正多边形或圆的程序。( lesson7_3)

clear,a=30;t=(0:a)/a*2*pi;sss={'base','caller','self'};

for k=1:3

y0=lesson7_3(8,sss{k});

subplot(1,3,k)

plot(real(y0),imag(y0),'r','LineWidth',3),axis square image

end

Page 36: 第七章  M  文件和面向对象编程

2 、跨空间赋值assignin(‘workspace’,’VN’,x)跨空间向 VN 变量赋值[lesson7_4.m]function y= lesson7_4(x)y=sqrt(x);t=x^2;assignin('base','yy',t)

Page 37: 第七章  M  文件和面向对象编程

7.4.4 子函数和私用函数1 、子函数

matlab允许 1 个 M 函数文件包含多个函数的代码。其中,第一个出现的称为主函数,该文件中其他的函数则称为子函数。保存时所用函数文件名与主函数定义名相同。外部程序只能对主函数进行调用。

Page 38: 第七章  M  文件和面向对象编程

子函数性质: 每个子函数的第一行是其自己的函数申明行 在 M 函数文件内,主函数的位置不可改变,但子函数的排列次序可以任意改变子函数只能被处于同一文件的主函数或其他子函数调用 在 M 函数文件中,任何指令通过“名字”对函数进行调用时,子函数的优先级仅次于内装函数 同一文件的主函数、子函数的工作空间都是彼此独立的。

Page 39: 第七章  M  文件和面向对象编程

2 、私有函数所谓私用函数,是指位于 private目录上的 M 文件函数,性质:

私用函数的构造与普通 M 函数完全相同私用函数只能被 private 直接父目录上的 M 文件所调用,而不能被其他目录上的任何 M 文件或 matlab指令窗中的命令所调用 M 文件中,任何指令通过“名字”对函数进行调用时,私用函数的优先级虽低于内装函数和子函数,但高于其他任何目录上的函数。

Page 40: 第七章  M  文件和面向对象编程

7.5 串演算函数为了提高计算的灵活性, matlab提供一种利用字符串进行计算的能力。7.5.1 evaly=eval(‘CEM’)执行 CEM 指定的计算;y=eval(‘CEM1’,’CEM2’)先执行 CEM1 指定的计算,如果出错,就执行 CEM2[y1,y2,…]=eval(‘CEM’)执行 CEM代表的函数文件调用,并输出计算结果。

Page 41: 第七章  M  文件和面向对象编程

说明 eval 指令的输入参数必须是字符串 构成字符串的 CEM ,可以是 matlab 任何合法的指 令、表达式、语句或 M 文件名 第 3 种格式种的 CEM 只能是 M 函数文件名。例 计算“表达式”串,产生向量值。clear,t=pi;cem='[t/2,t*2,sin(t)]';y=eval(cem)

Page 42: 第七章  M  文件和面向对象编程

例 计算“语句”串,创建变量。clear,t=pi;eval('theta=t/2,y=sin(theta)');who

例 计算“替代”串。A=ones(2,1);B=ones(1,3);c=eval('B*A','A*B');errmessage=lasterr

例 计算“合成”串。CEM={'cos','sin','tan'};for k=1:3theta=pi*k/12;y(1,k)=eval([CEM{1},'(',num2str(theta),')']);end

Page 43: 第七章  M  文件和面向对象编程

7.5.2 feval

[y1,y2,…]=feval(‘FN’,arg1,arg2,…)用参量 arg1 , arg2 等执行 FN 函数指定的计算。说明: ‘FN’ 只能是函数名。 在既可以使用 eval ,又可以使用 feval 的情况下, f

eval 运行效率更高。

Page 44: 第七章  M  文件和面向对象编程

feval 和 eval 运行区别: feval 的 FN 绝对不能是表达式x=pi/4;Ve=eval('1+sin(x)')Vf=feval('1+sin(x)',x)

feval 和 eval 调用区别: feval 的 FN 只接受函数名。randn('seed',1);A=rand(2,2);[ue,de,ve]=eval('svd(A)');disp('Results by eval');disp([ue,de,ve]);disp(blanks(1))[uf,df,vf]=feval('svd',A);disp('Results by feval');disp([uf,df,vf])

Page 45: 第七章  M  文件和面向对象编程

7.5.3 内联函数1 、 内联函数的创建inline(‘CE’)把串表达式转化为输入参数自动生成的内联函数;inline(‘CE’,arg1,arg2,…)把串表达式转化为 arg1,arg2 等指定输入参数的内联函数;inline(‘CE’,n)把串表达式转化为 x,P1,P2,…Pn 等指定输入参数的内联函数

Page 46: 第七章  M  文件和面向对象编程

2 、涉及内联函数性质的指令class(inline_fun)给出内联函数类型char(inline_fun)给出内联函数计算公式;argnames(inline_fun)给出内联函数的输入参数vectorize(inline_fun)使用内联函数适用”数组运算”规则。

Page 47: 第七章  M  文件和面向对象编程

3 、内联函数创建和应用示例内联函数的第一种创建格式适于“数组运算”。clear,F1=inline('sin(rho)/rho');f1=F1(2);FF1=vectorize(F1);xx=[0.5,1,1.5,2];ff1=FF1(xx);第一种内联函数创建格式的缺陷;含向量的多宗量输入的赋值。G1=inline('a*exp(x(1))*cos(x(2))'),G1(2,[-1,pi/3]);G2=inline('a*exp(x(1))*cos(x(2))','a','x'),G2(2,[-1,pi/3])

Page 48: 第七章  M  文件和面向对象编程

产生向量输入、向量输出的内联函数;Y2=inline('[x(1)^2;3*x(1)*sin(x(2))]')argnames(Y2)x=[4,pi/6];y2=Y2(x)

最简练格式创建内联函数;内联函数可被 feval 指令调用Z2=inline('P1*x*sin(x^2+P2)',2)z2=Z2(2,2,3)fz2=feval(Z2,2,2,3)

Page 49: 第七章  M  文件和面向对象编程

7.6 面向对象编程1 、类和对象

类名 含义cell 元胞数组char 字符串数组

double 双精度数值数组sparse 稀疏矩阵struct 构架数组

matlab 内装类

Page 50: 第七章  M  文件和面向对象编程

2 、新类应包含的基本内容( 1 )创建类目录( 2 )选定待建类的数据结构( 3 )对象构造函数( 4 )显示函数( 5 )与其他类之间的转换函数( 6 )其他重载函数和重载运算(参见 queue 类)

Page 51: 第七章  M  文件和面向对象编程

( 1 )创建一个队列对象,并显示qe='Hello! 你好 ! ';Q=queue(qe)( 2 )类别检查和对象判断class(Q)isobject(Q)isa(Q,'queue')( 3 )“空”队列判断isempty(Q)

Page 52: 第七章  M  文件和面向对象编程

( 4 )利用“入队”函数,使队列变长a=[1,2,3;4,5,6];b{1}='This';b{2}=' is ';b{3}='a cell array';comein(Q,a,b)( 5 )显示队列 Q 中具体元素的内容display(Q,2)( 6 )把 Q队列第一个元素和其余部分分离,并生成新队列 QQ[nn,vv,QQ]=goout(Q)( 7 )采用双下标法,显示 QQ(1,2) 的内容display(QQ,1,1), display(QQ,1,2)

Page 53: 第七章  M  文件和面向对象编程

3 、继承性及其应用class 函数class(VN)返回变量 VN 的类别名字符串;V_obj = class(VS,’ClassName’)把构架 VS定义为 ClassName 类数据对象;V_obj =class(VS,’SubClassName’,Parent1,Parent2,…)把构架 VS定义为 Parent1 , Parent2 等父类的 SubClas

sName子类对象。

Page 54: 第七章  M  文件和面向对象编程

( 1 )堆栈对象的创建AA=' 继承性 ';ST=stack(AA)( 2 )类别检查class(ST)isa(ST,'stack')isa(ST,'queue')( 3 )“空”堆栈判断isempty(ST)

Page 55: 第七章  M  文件和面向对象编程

( 4 )把元素压入堆栈BB=1:6;CC=sym('x^2+4*x');comein(ST,BB,CC);( 5 )显示堆栈中第三元素的内容display(ST,3)( 6 )从堆栈弹出元素[Name1,Value1,ST_1]=goout(ST)

Page 56: 第七章  M  文件和面向对象编程

1 、 利用 for 循环找出 100~200 之间的所有素数。( rem(m,i))

练习题

Page 57: 第七章  M  文件和面向对象编程

disp('100~200 之间的所有素数为: ') for m=100:200 k=fix(sqrt(m)); %求 m 的算术平方根然后取整 . for i=2:k+1 if rem(m,i)==0 %求整数 m 与 i 的余数 break; end end if i>=k+1 disp(int2str(m)) % 以字符串的形式显示素数 . end end