1第6章M文件与程序设计复杂问题的解算需要借助MATLAB程序进行。这种程序的扩展名为m——故称为M文件。M文件分为(M)脚本文件和(M)函数文件。本章介绍编写MATLAB程序时常用的控制结构、函数文件的构造、主函数、子函数及述函数句柄的创建、观察和调用。6.1MATLAB控制流语法说明if表达式语句体1elseif语句体2else语句体3end1.若表达式返回数组,则仅当所有元素都不为零时为真;若数组为空,则为假。2.elseif和else可选,其中可有多个elseif。switch表达式case表达式1语句体1case{式2,式3…}语句体2otherwise语句体3end1.仅执行第一个满足条件的语句体。2.case后可用花括号把多个表达式以“或”逻辑连接起来。3.可有多个case语句。4.otherwise可选。forx=表达式语句体end1.执行确定次数的循环。2.表达式为矩阵时,x把矩阵按列拉长为向量取值。while表达式语句体end若表达式为真时,循环执行语句体。6.1.1if-else-end控制结构if-else-end指令为程序流提供了一种分支控制。2表6.1-1if-else-end分支结构的使用方式单分支双分支多分支ifexpr(commands)endifexpr(commands1)else(commands2)endifexpr1(commands)elseifexpr2(commands)…….else(commandsk)end当expr给出“逻辑1”时,(commands)指令组才被执行。当expr给出“逻辑1”时,(commands1)指令组被执行;否则,(commands2)被执行。expr1,expr2,…中,首先给出“逻辑1”的那个分支的指令组被执行;否则,(commandsk)被执行。该使用方法常被switch-case所取代。【例6.1-1】已知函数xxxexxyx111113,编写能对任意一组输入x值求相应y值的程序。(1)编写函数文件程序:functiony=exm060101(x)%y=exm060101(x)Functioncalculateofexample6.1-1n=length(x);fork=1:nifx(k)-1y(k)=x(k);elseifx(k)=1y(k)=exp(1-x(k));elsey(k)=x(k)^3;endend3(2)保存在搜索路径上(3)调用函数文件x=[-2,-1.2,-0.4,0.8,1,6]y=exm060101(x)6.1.2switch-case控制结构表6.1-2switch-case控制结构的使用方式指令格式含义switchexprcasevalue_1(commands1)casevalue_2(commands2)casevalue_k(commandsk)otherwise(commands)endexpr为根据此前给定变量进行计算的表达式value_1是给定的数值、字符串标量(或单元数组)若expr结果与value_1(或其中的单元元素)相等,则执行。value_k是给定的数值、字符串标量(或单元数组)若expr结果与value_k(或其中的单元元素)相等,则执行。该情况是以上的“并”的“补”若所有case都不发生,则执行该组命令。【例6.1-2】已知学生的名字和百分制分数。要求根据学生的百分制分数,分别采用“满分”、“优秀”、“良好”、“及格”和“不及格”等表示学生的学习成绩。clear;fork=1:10a(k)={89+k};b(k)={79+k};c(k)={69+k};d(k)={59+k};end;c=[d,c];%A=cell(3,5);4A(1,:)={'Jack','Marry','Peter','Rose','Tom'};A(2,:)={72,83,56,94,100};%fork=1:5switchA{2,k}case100r='满分';casear='优秀';casebr='良好';casecr='及格';otherwiser='不及格';endA(3,k)={r};endA6.1.3for循环和while循环表6.1-3循环结构的使用方式for循环while循环forix=array(commands)endwhileexpression(commands)end【例6.1-3】创建Hilbert矩阵。(1)Hilbert矩阵11),(jijia。(2)K=5;A=zeros(K,K);form=1:Kforn=1:KA(m,n)=1/(m+n-1);end5endformatratA%formatshortgA=Columns1through411/21/31/41/21/31/41/51/31/41/51/61/41/51/61/71/51/61/71/8Column51/51/61/71/81/9(3)clearticK=1000;form=1:Kforn=1:KA1(m,n)=1/(m+n-1);endendt1=tocticK=1000;A2=zeros(K,K);form=1:Kforn=1:KA2(m,n)=1/(m+n-1)endendt2=toc(4)ticN=1000;n=repmat(1:N,N,1);m=n';A3=1./(n+m-1);t3=toc6clearticN=5;n=repmat(1:N,N,1);m=n';A3=1./(n+m-1);t3=tocformatratA3A3=10.50.333330.250.20.50.333330.250.20.166670.333330.250.20.166670.142860.250.20.166670.142860.1250.20.166670.142860.1250.11111t3=0.66052A3=Columns1through411/21/31/41/21/31/41/51/31/41/51/61/41/51/61/71/51/61/71/8Column51/51/61/71/81/9【例6.1-5】创建n阶魔方矩阵,限定条件是n为能被4整除的偶数。%exm060105.m生成一类魔方矩阵,该魔方矩阵的阶n为能被4整除的偶数。%A为魔方矩阵%n魔方矩阵的阶数clearclcwhile1n=input('请输入一个能被4整除的正整数!n=');ifmod(n,4)==0breakendendG=logical(eye(4,4)+rot90(eye(4,4)));m=n/4;K=repmat(G,m,m);N=n^2;7A=reshape(1:N,n,n);A(K)=N-A(K)+1验证所生成的魔方阵正确与否的程序:s0=round(n*(n*n+1)/2);disp([int2str(n),'阶魔方矩阵的标称和是',int2str(s0)])Ns0=round(2*(n+1));B=A';SC=sum(A);SR=sum(B);Sd=sum(diag(A));Sdi=sum(diag(B));LS=[SC,SR,Sd,Sdi]==s0;NS=round(sum(LS));ifNS==Ns0disp('经验证,A是魔方矩阵。')elsedisp('经验证,A不是魔方矩阵。')end6.1.4控制程序流的其它常用指令表6.1-4控制程序流的其它常用指令指令格式使用说明v=input('message')v=input('message','s')该指令执行时,“控制权”交给键盘;待输入结束,按下Enter键,“控制权”交还MATLAB。message是提示用的字符串。keyboard遇到keyboard时,将“控制权”交给键盘,用户可以从键盘输入各种MATLAB指令。breakbreak指令,或导致包含该指令的while、for循环终止,或在if-end,switch-case,try–catch中导致中断。参见例6.1-5。continue跳过位于它之后的循环体中其他指令,而执行循环的下一个迭代..见例6.1-5。pausepause(n)第一种格式使程序暂停执行,等待用户按任意键继续;第二种格式使程序暂停n秒后,再继续执行。return结束return指令所在函数的执行,而把控制8转至主调函数或者指令窗。否则,只有待整个被调函数执行完后,才会转出。try语句体1catch语句体2end1.语句体1总被执行,若没有错误则跳出try/catch块。2.若语句体1执行过程中发生错误,则执行语句体2。3.可以嵌套使用。利用try-catch模块,MATLAB编译系统发现的错误将被用户捕获,用户可以控制MATLAB怎样对发生的错误进行处理。error('e1:%sbad',svar)显示错误信息并退出程序。warning显示警告信息但不退出程序。dbstopifallerror如遇错误/警告,则停止执行并进入调试状态6.2脚本文件和函数文件注意:用户自己创建的M文件的文件名要避免与MATLAB的内建函数和工具箱中的函数重名,以免发生内置函数被替换的情况。6.2.1M脚本文件对于一些比较简单的问题,从指令窗中直接输入指令进行计算是十分轻松简单的事。但随指令数的增加,或随控制流复杂度的增加,或重复计算要求的提出,直接从指令窗进行计算就显得烦琐。而此时脚本文件最为适宜。“脚本”本身反映这样一个事实:MATLAB只是按文件所写的指令执行。脚本文件的特点是:它只是一串按用户意图排列而成的MATLAB指令集合。脚本文件运行后,产生的所有变量都驻留在MATLAB基本工作空间中。只要用户不使用clear指令加以清除,这些变量将一直保存在基本工作空间(Baseworkspace)中。基本空间随MATLAB的启动而产生;只有当关闭MATLAB时,该基本空间才被删除。6.2.2M函数文件函数文件犹如一个“黑箱”。从外界只看到:传给它的输入量和送出来的计算结果。而内部运作是藏而不见的。9函数文件的特点是:(1)从形式上看,与脚本文件不同,函数文件的第一行总是以function引导的“函数申明行”。该行还罗列出函数与外界的联系的全部“标称”输入输出宗量。但对“输入输出宗量”的标称数目并没有限制,即可以完全没有输入输出宗量,也可以是任意数目。(2)MATLAB允许使用比“标称数目”较少的输入输出宗量,实现对函数的调用。在一次调用中所用到的输入和输出变量的个数可以通过分别调用函数nargin和nargout来确定。因为nargin和nargout是函数而不是变量,所以用户不能用诸如nargin=nargin+pi之类的语句对它们进行重新赋值。(3)从运行上看,与脚本文件运行不同,每当函数文件运行,MATLAB就会专门为它开辟一个临时工作空间,称之谓函数工作空间(Functionworkspace)。所有中间变量都存放在函数工作空间中。当执行完文件最后一条指令或遇到return时,就结束该函数文件的运行,同时该临时函数空间及其所有的中间变量就立即被清除。(4)函数空间随具体M函数文件的被调用而产生,随调用结束而删除。函数空间是相对基本空间独立的、临时的。在MATLAB整个运行期间,可以产生任意多个临时函数空间。(5)假如在函数文件中,发生对某脚本文件的调用,那么该脚本文件运行产生的所有变量都存放于该函数空间之中,而不是存放在基本空间。6.2.3局部变量和全局变量(1)局部(Local)变量存在于函数空间内部的中间变量,产生于该函数的运行过程中,其影响范围也仅限于该函数本身。正由于这种空间、时间上的局部性,中间变量被称为局部变量。(2)全局(Global)变量通过global指令,MATLAB也允许几个不同的函数空间以及基本工作空间共享同一个变量。这种被共享的变量称为全局变量。每个希望共享全局变量的函数或MATLAB基本工作空间,10必须逐个用global对具体变量加以专门定义