1、matlab入门经典教程ch07第七章 M文件和面向对象编程 假如读者想灵活运用MATLAB去解决实际问题,想充分调动MATLAB科学技术资源,想理解MATLAB版本升级所依仗的基础,那么本章内容将十分有用。 本章将涉及比较深层的MATLAB内容:脚本;函数(一般函数、内联函数、子函数、私用函数、方法函数);函数句柄的创建和使用;程序调试和剖析;数据结构(类、对象);重载和继承;面向对象编程。本章配备了许多精心设计的算例。这些算例是完整的,可直接演练的。读者通过这些算例,将真切感受到抽象概念的内涵、各指令间的协调,将从感知上领悟到面向对象编程的优越和至关要领。 本章新增了第7.7节,专门阐述函
2、数句柄的创建和使用,它适用于MATLAB6.x版;而新增的第7.9.3节中关于程序性能优化的内容,则仅适用于MATLAB6.5以后版。7.1入门【例7.1-1】通过M脚本文件,画出下列分段函数所表示的曲面。(1)图 7.1-1 exm0701_1.m%exm0701_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); elseif x(j)+y(i)=-1 z(i,
3、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);(2)exm0701_1 图 7.1-2 【例7.1-2】通过M函数文件画出上例分段函数的曲面。exm0701_2(2,2)7.2 M文本编辑器7.3 MATLAB控制流7.3.1for循环结构【例7.3.1-1】一个简单的for循环示例。for i=1:1
4、0;x(i)=i;end; x x = 1 2 3 4 5 6 7 8 9 10 7.3.2while循环结构【例7.3.2-1】Fibonacci数组的元素满足Fibonacci 规则: ,;且。现要求该数组中第一个大于10000的元素。a(1)=1;a(2)=1;i=2;while a(i)8 sums=number*0.95*cost;end,sums sums = 114.0000 【例7.3.3-2】用for循环指令来寻求Fibonacc数组中第一个大于10000的元素。n=100;a=ones(1,n);for i=3:n a(i)=a(i-1)+a(i-2); if a(i)=1
5、0000 a(i), break; end;end,i ans = 10946i = 21 7.3.4switch-case结构【例7.3.4-1】学生的成绩管理,用来演示switch结构的应用。clear;%for i=1:10;ai=89+i;bi=79+i;ci=69+i;di=59+i;end;c=d,c;Name= Jack,Marry,Peter, Rose, Tom;Mark=72,83,56,94,100;Rank=cell(1,5);%S=struct(Name,Name,Marks,Mark,Rank,Rank);%for i=1:5 switch S(i).Marks c
6、ase 100 S(i).Rank=满分; case a S(i).Rank= 优秀; case b S(i).Rank= 良好; case c S(i).Rank= 及格; otherwise S(i).Rank=不及格; endend%disp(学生姓名 , 得分 , 等级);disp( )for i=1:5; disp(S(i).Name,blanks(6),num2str(S(i).Marks),blanks(6),S(i).Rank);end; 学生姓名 得分 等级 Jack 72 及格Marry 83 良好Peter 56 不及格 Rose 94 优秀 Tom 100 满分 7.3
7、.5try-catch结构【例7.3.5-1】try-catch结构应用实例:对魔方阵的行进行援引,当“行下标”超出魔方阵的最大行数时,将改向对最后一行的援引,并显示“出错”警告。clear,N=4;A=magic(3);try A_N=A(N,:)catch A_end=A(end,:)endlasterr A_end = 4 9 2ans = Index exceeds matrix dimensions. 7.3.6控制程序流的其它常用指令7.3.6.1return指令7.3.6.2input和keyboard指令7.3.6.3yesinput指令7.3.6.4pause指令7.3.6.
8、5break指令7.3.6.6error和warning指令7.4脚本文件和函数文件7.4.1M脚本文件7.4.2M函数文件7.4.3局部变量和全局变量7.4.4M文件的一般结构【例7.4.4-1】M函数文件示例。本例演示:(A)编写一个画任意半径任意色彩线型的圆。(B)完整函数文件的基本结构。(C)函数文件各基本组成部分的作用。exm07044_1.mfunction sa = exm07044_1(r,s)%CIRCLE % % if nargin2 error(输入宗量太多。);end;if nargin=1 s=b;end;clf;t=0:pi/100:2*pi;x=r*exp(i*t
9、);if nargout=0 plot(x,s);else sa=pi*r*r; fill(real(x),imag(x),s)endaxis(square)7.4.5P码文件7.4.5.1语法分析过程和伪代码7.4.5.2P码文件的预生成7.4.5.3内存中P码文件的列表和清除7.4.6MATLAB的搜索过程7.5变量的检测传递和限权使用函数7.5.1输入输出宗量检测指令7.5.2“变长度”输入输出宗量【例7.5.2-1】变长度宗量使用示例。(1) exm07052_1.mfunction varargout = exm07052_1(r,varargin)%RINGZY Plot a ri
10、ng and calculate the area of the ring.%vin=length(varargin);Nin=vin+1; % error(nargchk(1,Nin,nargin) %if nargout6 % error(Too many output arguments)endt=0:pi/20:2*pi;x=r*exp(i*t);s=pi*r*r;if nargout=0 switch Nin case 1 plot(x,b) case 2 r2=varargin1; % x2=r2*exp(i*t); plot(x,b);hold on ;plot(x2,b);ho
11、ld off otherwise r2=varargin1; % x2=r2*exp(i*t); plot(x,varargin2:end);hold on % plot(x2,varargin2:end);hold off % end; axis(square)else varargout1=real(x);varargout2=imag(x); % varargout5=pi*r*r;varargout6=; % if Nin1 r2=varargin1; % x2=r2*exp(i*t); varargout3=real(x2);varargout4=imag(x2); % vararg
12、out6=pi*(r2-r22); % end;end (2)r1=1;r2=3;x1,y1,x2,y2,s1,s2=exm07052_1(r1);x1,y1,x2,y2=exm07052_1(r1,r2);x1,y1,x2,y2,s1,s2=exm07052_1(r1,r2);(3)r1=1;r2=0.6;subplot(1,3,1),exm07052_1(r1,r2),subplot(1,3,2),exm07052_1(r1,r2,Marker,o) subplot(1,3,3),exm07052_1(r1,r2,LineWidth,5,Color,1 0.4 0) 图 7.5-1 7.5
13、.3跨空间变量传递7.5.3.1跨空间计算串表达式的值【例7.5.3.1-1】本例演示:(A)编写绘制正多边形或圆的程序。(B)子函数与(母)函数的关系。(C)各种不同的工作空间。(D)evalin运行机理与eval的异同。(1)exm070531_1.mfunction y1=exm070531_1(a,s)t=(0:a)/a*2*pi;y1=subevalinzzy(4,s);%- subfunction -function y2=subevalinzzy(a,s)t=(0:a)/a*2*pi;ss=a*exp(i*t);switch scase base,caller y2=evalin
14、(s,ss);case self y2=eval(ss);end(2)clear,a=30;t=(0:a)/a*2*pi;sss=base,caller,self;for k=1:3 y0=exm070531_1(8,sssk); subplot(1,3,k) plot(real(y0),imag(y0),r,LineWidth,3),axis square imageend 图 7.5-2 7.5.3.2跨空间赋值【例7.5.3.2-1】assignin运作机理示范。(1)exm070532_1.mfunction y=exm070532_1(x)y=sqrt(x);t=x2;assigni
15、n(base,yy,t)(2)clear;x=4;y=exm070532_1(x);disp(blanks(5),x,blanks(5),y,blanks(4),yy),disp(x,y,yy) x y yy 4 2 16 7.5.4子函数和私用函数7.5.4.1子函数7.5.4.2私用函数7.6串演算函数7.6.1eval【例7.6.1-1】计算“表达式”串,产生向量值。clear,t=pi;cem=t/2,t*2,sin(t);y=eval(cem) y =1.5708 6.2832 0.0000【例7.6.1-2】计算“语句”串,创建变量。clear,t=pi;eval(theta=t/
16、2,y=sin(theta);who theta = 1.5708y = 1Your variables are:t theta y 【例7.6.1-3】计算“替代”串。A=ones(2,1);B=ones(1,3);c=eval(B*A,A*B),errmessage=lasterr c = 1 1 1 1 1 1errmessage =Error using = *Inner matrix dimensions must agree. 【例7.6.1-4】计算“合成”串。CEM=cos,sin,tan;for k=1:3 theta=pi*k/12; y(1,k)=eval(CEM1,(,
17、num2str(theta),);endy y = 0.9659 0.8660 0.7071 7.6.2feval【例7.6.2-1】feval 和eval 运行区别之一:feval的FN绝对不能是表达式。x=pi/4;Ve=eval(1+sin(x) Ve = 1.7071 Vf=feval(1+sin(x),x) ? Error using = fevalInvalid function name 1+sin(x). 【例7.6.2-2】feval 和eval 调用区别:feval 的FN只接受函数名。本例两种方法以后者为好。randn(seed,1);A=rand(2,2);ue,de,
18、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) Results by eval -0.9193 -0.3936 1.2212 0 -0.7897 -0.6135 -0.3936 0.9193 0 0.2633 -0.6135 0.7897 Results by feval -0.9193 -0.3936 1.2212 0 -0.7897 -0.6135 -0.3936 0.9193 0 0.2
19、633 -0.6135 0.7897 7.6.3内联函数7.6.3.1内联函数的创建7.6.3.2涉及内联函数性质的指令7.6.3.3内联函数创建和应用示例【例7.6.3.3-1】演示:内联函数的第一种创建格式;使内联函数适于“数组运算”。clear,F1=inline(sin(rho)/rho) F1 = Inline function: F1(rho) = sin(rho)/rho f1=F1(2) f1 = 0.4546 FF1=vectorize(F1)xx=0.5,1,1.5,2;ff1=FF1(xx) FF1 = Inline function: FF1(rho) = sin(rh
20、o)./rhoff1 = 0.9589 0.8415 0.6650 0.4546 【例7.6.3.3-2】演示:第一种内联函数创建格式的缺陷;含向量的多宗量输入的赋值。G1=inline(a*exp(x(1)*cos(x(2),G1(2,-1,pi/3) G1 = Inline function: G1(a) = a*exp(x(1)*cos(x(2)? Error using = inline/subsrefToo many inputs to inline function. G2=inline(a*exp(x(1)*cos(x(2),a,x),G2(2,-1,pi/3) G2 = Inl
21、ine function: G2(a,x) = a*exp(x(1)*cos(x(2)ans = 0.3679 【例7.6.3.3-3】演示:产生向量输入、向量输出的内联函数;这种向量函数的调用方法。Y2=inline(x(1)2;3*x(1)*sin(x(2)argnames(Y2) Y2 = Inline function: Y2(x) = x(1)2;3*x(1)*sin(x(2)ans = x x=4,pi/6;y2=Y2(x) y2 = 16.0000 6.0000 【例7.6.3.3-4】演示:最简练格式创建内联函数;内联函数可被feval 指令调用。Z2=inline(P1*x*
22、sin(x2+P2),2) Z2 = Inline function: Z2(x,P1,P2) = P1*x*sin(x2+P2) z2=Z2(2,2,3)fz2=feval(Z2,2,2,3) z2 = 2.6279fz2 = 2.6279 7.7函数句柄7.7.1函数句柄的创建和观察【例7.7.1-1】为MATLAB的“内建”函数创建函数句柄,并观察其内涵。(1)hsin=sin; (2)class(hsin)size(hsin) ans =function_handleans = 1 1 (3)CC=functions(hsin) CC = function: sin type: ove
23、rloaded file: MATLAB built-in function methods: 1x1 struct (4)CC.methods.sym ans =d:matlab6p5toolboxsymbolicsymsin 7.7.2函数句柄的基本用法【例7.7.2-1】本例通过函数及其句柄演示若干基本用法。(1)fhandle=str2func(sin); (2)ys=sin(pi/4)yfold=feval(sin,pi/4)yfnew=feval(fhandle,pi/4) ys = 0.7071yfold = 0.7071yfnew =0.7071 (3)Alpha=sym(pi
24、/4);yss=sin(Alpha)yfold=feval(sin,Alpha)ynews=feval(sin,Alpha) yss =1/2*2(1/2)yfold =1/2*2(1/2)ynews =1/2*2(1/2) (4)xold=fminbnd(sin,0,2*pi)xnew=fminbnd(fhandle,0,2*pi) xold = 4.7124xnew = 4.7124 【例7.7.2-2】本例演示:如何避免创建“无效函数句柄“问题。(1)Hy2=fhzzy %fhzzy.m是随书光盘mfiles文件夹上的一个函数文件。 Hy2 = fhzzy (2)class(Hy2)si
25、ze(Hy2) ans =function_handleans = 1 1 (3)feval(Hy2,line); ? Error using = fevalUndefined function fhzzy. 【例7.7.2-3】自建函数及其句柄的使用。(1)fhzzy.mfunction Hr=fhzzy(flag )% fhzzy % % t=(0:100)/100*2*pi;x=sin(t);y=cos(t);Hr=cirline;feval(Hr,flag,x,y,t)% -subfunction-function cirline(wd,x,y,t)% %switch wdcase l
26、ine plot(t,x,b ,t,y,r,LineWidth,2)case circle plot(x,y,g.,MarkerSize,30), axis square offotherwise error(输入宗量只能取 line 或 circle ! )endshg(2)Hy3=fhzzyfhzzy(line); Hy3 = fhzzy图7.7-1 (3)which(fhzzy) fhzzy not found. (4)fhzzy(line)feval(fhzzy,line) ? Undefined function or variable fhzzy. (5)feval(Hy3,lin
27、e); 【例7.7.2-4】子函数句柄的创建与使用。(1)HCL=fhzzy(circle) HCL = cirline图7.7-2(2)tt=(0:100)/100*2*pi;xx=sin(tt);yy=cos(tt);cirline(circle,xx,yy,tt);feval(circle,xx,yy,tt) ? Undefined function or variable cirline. (3)feval(HCL,circle,xx,yy,tt) 7.8创建用户工具箱7.8.1MATLAB对工具箱文件的管理特点7.8.2建立用户工具箱须知7.9调试和剖析7.9.1直接调试法7.9.2调试器的使用7.9.2.1图形式调试器图7.9-1