第四章MATLAB编程基础MATLAB基础与编程入门教学课件

上传人:re****.1 文档编号:589853720 上传时间:2024-09-11 格式:PPT 页数:158 大小:1,008KB
返回 下载 相关 举报
第四章MATLAB编程基础MATLAB基础与编程入门教学课件_第1页
第1页 / 共158页
第四章MATLAB编程基础MATLAB基础与编程入门教学课件_第2页
第2页 / 共158页
第四章MATLAB编程基础MATLAB基础与编程入门教学课件_第3页
第3页 / 共158页
第四章MATLAB编程基础MATLAB基础与编程入门教学课件_第4页
第4页 / 共158页
第四章MATLAB编程基础MATLAB基础与编程入门教学课件_第5页
第5页 / 共158页
点击查看更多>>
资源描述

《第四章MATLAB编程基础MATLAB基础与编程入门教学课件》由会员分享,可在线阅读,更多相关《第四章MATLAB编程基础MATLAB基础与编程入门教学课件(158页珍藏版)》请在金锄头文库上搜索。

1、第四章 MATLAB编程基础 第四章 MATLAB编程基础 4.1 概述概述 4.2 流程控制流程控制 4.3 脚本文件脚本文件 4.4 函数文件函数文件 4.5 M文件调试文件调试 4.6 M文件性能分析文件性能分析 4.7 本章小结本章小结 第四章 MATLAB编程基础 4.1 概概 述述 MATLAB提供了完整的编写应用程序的能力,这种能力通过一种被称为M语言的高级语言来实现。这种编程语言是一种解释性语言,利用该语言编写的代码仅能被MATLAB接受,被MATLAB解释、执行。其实,一个M语言文件就是由若干MATLAB的命令组合在一起构成的,这些命令都是在前面章节中介绍的合法的MATLAB

2、命令。和C语言类似,M语言文件都是标准的纯文本格式的文件,其文件的扩展名为.m。第四章 MATLAB编程基础 使用M文件最直接的好处就是可以将一组MATLAB命令组合起来,通过一个简单的指令就可以执行这些命令。这些命令可以完成某些MATLAB的操作,也可以实现某个具体的算法。其实,MATLAB产品族中包含的工具箱就是由世界上在相应专业领域内的顶尖高手,利用M语言开发的算法函数文件集合。读者也可以结合自己工作的需要,为自己的MATLAB开发具体的算法和工具箱。MATLAB的函数主要有两类,一类被称为内建(Build-in)函数,这类函数是由MATLAB的内核提供的,能够完成基本的运算,例如三角函

3、数、矩阵运算的函数等。另外一类函数就是利用高级语言开发的函数文件,这里的函数文件既包括用C语言开发的MEX函数文件,又包含了M函数文件。有关MEX函数文件的内容已经超出了本书的内容,将在MATLAB外部编程接口一书中详细讲述。第四章 MATLAB编程基础 如前所述,MATLAB的M语言文件是纯文本格式的文件,利用任何一种纯文本编辑器都可以编写相应的文件,例如Windows平台下的记事本、UltraEdit等软件,或者Unix平台下的Emacs软件等。同样,为了方便编辑M文件,MATLAB也提供了一个编辑器,叫作meditor,它也是系统默认的M文件编辑器。运行meditor的方法非常简单,在M

4、ATLAB命令行窗口中键入下面的指令就可以打开meditor:edit这时MATLAB将启动meditor,然后创建一个未命名的空白文件,如图4-1所示。第四章 MATLAB编程基础 图4-1meditor的运行界面第四章 MATLAB编程基础 这时用户就可以直接在编辑器中键入MATLAB指令,开发M语言文件了。此外,运行meditor还可以通过“File”菜单中“New”子菜单下的“M-File”命令来实现,或者直接单击MATLAB用户界面工具栏上的新建按钮完成同样的工作。M语言文件可以分为两类,其中一类是脚本文件,另外一类叫作函数文件。本章将分别介绍这两类文件的编写方法。第四章 MATLA

5、B编程基础 4.2 流流 程程 控控 制制 4.2.1 选择结构选择结构如前所述,当人们判断某一条件是否满足,根据判断的结果来选择不同的解决问题的方法时,就需要使用选择结构。和C语言类似,MATLAB的条件判断可以使用if语句或者switch语句。第四章 MATLAB编程基础 4.2.1.1 if语句语句if语句的基本语法结构有三种,分别如下:(1)if(关系运算表达式)MATLAB语句end这种形式的选择结构表示,当关系运算表达式计算的结果为逻辑真的时候,执行MATLAB语句,这里的MATLAB语句可以是一个MATLAB表达式,也可以是多个MATLAB表达式。在MATLAB语句的结尾处,必须

6、有关键字end。第四章 MATLAB编程基础 (2)if(关系运算表达式)MATLAB语句AelseMATLAB语句Bend这种选择结构表示,当关系运算表达式的计算结果为逻辑真的时候,执行MATLAB语句A,否则执行MATLAB语句B,在语句B的结尾必须具有关键字end。第四章 MATLAB编程基础 (3)if(关系运算表达式a)MATLAB语句Aelseif(关系运算表达式b)MATLAB语句Belse(关系运算表达式c)end这种选择结构可以判断多条关系运算表达式的计算结果,然后按照执行的逻辑关系执行相应的语句。读者可以根据类似的C语言知识或者前面两种选择结构的介绍判断这种结构的执行方式。

7、第四章 MATLAB编程基础 例子例子4-1if语句的使用if_examp.m。读者通过本例子将同时了解meditor的基本使用方法。打开meditor,然后键入下面的指令:001clearall002003I=1;004J=2;005006ifI=J007A(I,J)=2;008elseifabs(I-J)=1009A(I,J)=?1;010else011A(I,J)=0;012end第四章 MATLAB编程基础 注意:在键入程序时,不要将行号(001012)也敲进去,在这里设置行号的主要目的是为了便于讲解和分析程序。所有的指令键入完毕后,将文件保存,读者可以将其保存为任何名字,不过文件名必

8、须由英文字符和数字组成,将文件的扩展名设置为.m,并且将文件保存在MATLAB的搜索路径下,例如MATLAB当前的工作路径。然后在MATLAB的命令行中,键入刚才保存的文件名,不过,这时不要将扩展名也一同键入,MATLAB就会依次执行这些指令。第四章 MATLAB编程基础 运行例子4-1的方法和效果如下:if_exampA=0-1例子4-1代码的核心是006012行的部分,这部分展示了if-elseif-else-end语句组合的使用方法。请读者仔细察看,并且通过修改程序003和004行中对I和J的赋值来察看整个语句的执行情况。和C语言类似,if-elseif-else的语句结构也可以嵌套地使

9、用,也就是可以存在这样的语句结构:第四章 MATLAB编程基础 if(关系表达式a)if(关系表达式b)MATLAB语句AelseMATLAB语句Bendelseif(关系表达式c)MATLAB语句CelseMATLAB语句Dendend第四章 MATLAB编程基础 注意:在使用嵌套的选择结构时,需要小心if语句和end关键字的配对。例子例子4-2嵌套使用的if结构if_examp2.m。001clearall002003if1004disp(Is1)005else006disp(Not1)007end008第四章 MATLAB编程基础 009I=1;010ifI011ifI-2016dis(

10、Iislessthan0butbiggerthan-2)017end018end第四章 MATLAB编程基础 该程序的运行方法和效果如下:if_examp2Is1Iisbiggerthan0butlessthan2在例子4-2中,主要说明了嵌套的if结构和在关系表达式中使用常量的方法。在代码的003行,if语句的关系表达式为常数1,这个时候if语句将始终认为非零值为逻辑真,所以,程序执行了004行的代码。同样,在程序的009行,if语句的关系表达式为变量I,若I的数值为非零值,则if语句判断其为逻辑真,所以,代码的016行只有在I为0时,才可能被执行。第四章 MATLAB编程基础 4.2.1.

11、2 switch语句语句另外一种构成选择结构的关键字就是switch。在处理实际问题的时候,往往要处理多个分支,这时如果使用if-else语句处理多分支结构往往使程序变得十分冗长,从而降低了程序的可读性。switch语句就可以用于处理这种多分支的选择,它的基本语法结构如下:第四章 MATLAB编程基础 switch(表达式)case常量表达式a:MATLAB语句Acase常量表达式b:MATLAB语句Bcase常量表达式m:MATLAB语句Motherwise:MATLAB语句Nend第四章 MATLAB编程基础 在switch语句之后的表达式可以是一个数值类型表达式或者是一个数值类型的变量,

12、当这个表达式的值同case后面的某一个常量表达式相等时,则执行该case后面的常量表达式后面的语句。注意:MATLAB的switch和C语言的switch语句结构不同。在C语言中,每一个case后面的语句中必须包含类似break语句的流程控制语句,否则程序会依次执行符合条件的case语句后面的每一个case分支。但是在MATLAB中就不必如此,程序仅仅执行符合条件的case分支。第四章 MATLAB编程基础 例子例子4-3switch结构使用示例switch_examp.m。001clearall002003algorithm=input(Enteranalgorithminquotes(od

13、e23,ode15s,etc:);004005switchalgorithm006caseode23007str=2nd/3rdorder;008caseode15s,ode23s009str=stiffsystem;010otherwise011str=otheralgorithm;012end013disp(str);第四章 MATLAB编程基础 该文件的运行方法和效果如下:switch_exampEnteranalgorithminquotes(ode23,ode15s,etc:)ode232nd/3rdorderswitch_exampEnteranalgorithminquotes(

14、ode23,ode15s,etc:)ode4otheralgorithm第四章 MATLAB编程基础 例子4-3中需要用户在执行程序的过程中输入一个字符串,switch语句根据用户的输入判断执行相应的case分支。若没有符合条件的case分支,则switch执行otherwise后面的语句。若switch结构中没有定义otherwise及其相应的代码,则程序不会进行任何操作,而是直接退出switch结构。提示:在处理以字符串变量或者常量参与的关系判断操作时,使用switch结构要比if-else结构效率高一些。由于MATLAB的switch结构没有C语言的fall-through特性,所以,如

15、果需要针对多个条件而使用同一个case分支的时候,需要使用元胞数组与之配合,参见例子4-4。第四章 MATLAB编程基础 例子4-4switch结构使用示例switch_examp2.m。001clearall002003var=input(InputaNumer:);004switchvar005case1006disp(1)007case2,3,4008disp(2or3or4)009case5010disp(5)011otherwise012disp(somethingelse)013end第四章 MATLAB编程基础 例子4-4运行的方法和效果如下:switch_examp2Input

16、aNumer:11switch_examp2InputaNumer:32or3or4switch_examp2InputaNumer:7somethingelse第四章 MATLAB编程基础 例子4-4代码的核心部分为007行,这里使用元胞数组增加判断条件的个数,当输入的数字为2、3或者4时,switch结构将使用同一个case分支进行判断、计算。注意:从代码的完整性和可靠性角度出发,在使用switch语句时,一定要包含otherwise分支,这是一种良好的编程习惯。第四章 MATLAB编程基础 4.2.2 循环结构循环结构在解决很多问题的时候需要使用循环结构,例如求解数列的和或者进行某种迭代

17、法求解数值方程时,都需要循环结构配合完成计算。在MATLAB中,包含两种循环结构,一种是循环次数不确定的while循环,而另一种是循环次数确定的for循环。第四章 MATLAB编程基础 1while循环结构循环结构while语句可以用来实现“当”型的循环结构,它的一般形式如下:while(表达式)MATLAB语句end当表达式为真时,循环将执行由语句构成的循环体,其特点是先判断循环条件,如果循环条件成立,即表达式运算结果为“真”,再执行循环体。循环体执行的语句可以是一句也可以是多句,在MATLAB语句之后必须使用关键字end作为整个循环结构的结束。另外,在循环过程中一定要能够改变关系表达式或者

18、布尔类型变量的值,或者使用其他方法来跳出循环,否则会陷入死循环(无法正常退出的循环叫作死循环)。第四章 MATLAB编程基础 例子例子4-5使用while语句求解。001i=1;002sum=0;003while(iwhile_example计算结果为:500500例子4-5的002006行使用了while循环结构,在循环结构中进行了累加的操作。需要注意的是,在MATLAB中没有类似C语言的+或者+=等运算操作符,因此在进行诸如累加或者递减的运算时,不得不给出完整的表达式。另外,例子4-5求数列和的算法的运算效率很低,在MATLAB中不要使用这样的结构完成类似的运算,而需要采用向量化的计算。第

19、四章 MATLAB编程基础 注意:while循环结构的关系表达式可以是某个数据变量或者常量,这时,将按照非零值为逻辑真进行相应的操作。另外,在进行上述操作时,若数据变量为空矩阵,则while语句将空矩阵作为逻辑假处理,也就是说,在whileAMATLAB语句S1end结构中,若A为空矩阵,则MATLAB语句S1永远不会被执行。第四章 MATLAB编程基础 2for循环结构循环结构使用for语句构成循环是最灵活、简便的方法,不过,使用for语句循环需要预先知道循环体执行的次数,所以这种循环一般叫作确定循环。在MATLAB中for循环的基本结构如下:forindex=start:increment

20、:endMATLAB语句end其中,index的取值取决于start和end的值,一般地,这里通常使用等差的数列向量,参见例子4-6。第四章 MATLAB编程基础 例子例子4-6使用for语句求解。001sum=0;002fori=1:1000003sum=sum+i;004end005str=计算结果为:,num2str(sum);006disp(str)第四章 MATLAB编程基础 例子4-6运行的结果为for_example计算结果为:500500在例子4-6中,002行的代码使用了确定次数的for循环结构,循环次数使用行向量进行控制,而且索引值i按照默认的数值1进行递增。在for循环语

21、句中,不仅可以使用行向量进行循环迭代的处理,也可以使用矩阵作为循环次数的控制变量,这时循环的索引值将直接使用矩阵的每一列,循环的次数为矩阵的列数,参见例子4-7。第四章 MATLAB编程基础 例子例子4-7for循环示例。001A=rand(3,4);002003fori=A004sum=mean(i)005end例子4-7运行的结果为for_matricessum=0.2728sum=0.6649sum=0.4275sum=0.5220第四章 MATLAB编程基础 例子4-7尽管只有短短的几行,但是在003行使用了一个矩阵作为循环的索引值,于是,循环结果就分别计算矩阵的每一列元素的均值。和其

22、他高级语言类似,MATLAB的循环结构也可以进行嵌套使用,使用嵌套的循环需要注意for关键字和end关键字之间的配对使用,请读者根据高级语言的一般特性来推断其运行的方式,这里就不再赘述了。第四章 MATLAB编程基础 4.2.3 break语句和语句和continue语句语句在循环结构中还有两条语句会影响程序的流程,这就是break语句和continue语句,这两条语句的基本功能如下:当break语句使用在循环体中的时候,其作用是能够在执行循环体的时候强迫终止循环,即控制程序的流程,使其提前退出循环,它的使用方法是break;continue语句出现在循环体中的时候,其作用是能够中断本次的循环

23、体运行,将程序的流程跳转到判断循环条件的语句处,继续下一次的循环,它的使用方法是continue;第四章 MATLAB编程基础 例子例子4-8break语句示例break_example.m。001i=0;002j=0;003k=0;004fori=1:2005forj=1:2006fork=1:2007if(k=2)008disp(退出循环);009break;010end第四章 MATLAB编程基础 011str=sprintf(I=%d,J=%d,K=%d,i,j,k);012disp(str);013end014end015end016disp(程序运行结束);第四章 MATLAB编程

24、基础 例子例子4-8 的运行结果如下:break_exampleI=1,J=1,K=1退出循环I=1,J=2,K=1退出循环I=2,J=1,K=1退出循环I=2,J=2,K=1退出循环程序运行结束第四章 MATLAB编程基础 break语句的作用是退出当前的循环结构运行,所以在例子4-8中,位于最内层循环的break语句执行的结果是退出了最内层的循环k,位于外层的循环i和j还是都运行完毕了。第四章 MATLAB编程基础 例子例子4-9continue语句示例。001i=0;002fori=1:6003if(i3)004continue005else006str=sprintf(I=%d,i);

25、007disp(str);008end009end010str=sprintf(循环结束I=%d,i);011disp(str);第四章 MATLAB编程基础 例子4-9的运行结果如下:continue_exampleI=1I=2I=3循环结束I=6continue语句的作用在例子4-9中得到了充分说明,该语句终止当前的循环,然后继续下一次循环运算,直到所有的循环迭代运算结束为止。第四章 MATLAB编程基础 4.2.4 提高运算性能提高运算性能M语言和其他的高级语言不同,由于采用了解释型语言,所以M语言的执行效率肯定低于编译型语言(例如C语言)。然而,随着MATLAB版本的不断升级,再加之合

26、理利用MATLAB向量运算等特点可以较大幅度地提高M语言代码的执行效率。在本小节结合一些具体的例子来讲述M语言编程以及MATLAB软件本身在提高程序执行效率方面的一些特性。第四章 MATLAB编程基础 1向量化运算向量化运算首先,希望读者牢记这样一点,MATLAB最初的目的是提供便利的矩阵数据操作能力。所以在大多数的应用程序中,不要使用循环结构操作矩阵的元素,应直接使用矩阵元素的索引或者矩阵运算的函数,这样做不仅能够提高代码的执行效率,而且还能够提高程序的可读性,这就是所谓的向量化的运算,也就是说,尽量将使用while循环或者for循环的语句结构转换成等价的向量或者矩阵运算,以提高程序的运算速

27、度,参见例子4-10。第四章 MATLAB编程基础 例子例子4-10向量化运算array_vs_loops.m。001Mass=rand(5,10000);002Length=rand(5,10000);003Width=rand(5,10000);004Height=rand(5,10000);005006rows,cols=size(Mass);007008disp(char(10),使用数组运算:)009tic010Density=Mass./(Length.*Width.*Height);011toc第四章 MATLAB编程基础 012013disp(char(10),使用循环结构:)

28、014tic;015forI=1:rows016forJ=1:cols017Density(I)=Mass(I,J)/(Length(I,J)*Width(I,J)*Height(I,J);018end019end020toc第四章 MATLAB编程基础 例子4-10比较了循环结构和数组运算的执行效率,程序中分别在010行使用数组运算和在015019行使用循环结构完成了同样的工作。程序的运行结果如下:array_vs_loops使用数组运算:elapsed_time=0使用循环结构:elapsed_time=0.0100第四章 MATLAB编程基础 2预分配存储空间预分配存储空间另外一种能够提

29、高运算效率的方法就是进行内存变量存储空间的预分配,首先察看例子4-11。例子4-11内存预分配的例子pre_allocate.m。001disp(char(10),使用内存预分配:)002pre_allo=zeros(10000,1);003tic;004forI=1:10000005pre_allo(I)=rand(1);006end第四章 MATLAB编程基础 007toc008009disp(char(10),不使用内存预分配:)010tic;011forJ=1:10000012not_pre_allo(J)=rand(1);013end014toc第四章 MATLAB编程基础 例子4-

30、11的执行结果如下:pre_allocate使用内存预分配:elapsed_time=0.0900不使用内存预分配:elapsed_time=0.3410第四章 MATLAB编程基础 上面两种不同的运算惟一的区别就是程序002行,执行这行语句之后,MATLAB自动分配了10000个连续的内存空间用于存储数据,MATLAB将一次创建足够的存储空间,然后依次赋值。而后者not_pre_alloc变量没有进行相应的操作,所以带来了两次运算结果的不同。在不使用内存预分配的运算中,MATLAB是如何进行操作的呢?当I=1时,MATLAB将使用一小块长度为一个单元大小的内存保存一位随机数。当I=2时,MA

31、TLAB寻找一块两单元大小的内存区,一个单元放第一个随机数,第二个放另外一个随机数。第四章 MATLAB编程基础 当I=10000时,MATLAB寻找一块容纳10000单元的内存区存放以前的9999个随机数,同时把最新的一个随机数加入进去。代码运行的结果造成了存储空间的浪费,降低了程序的执行速度。所以,在编写M语言程序的时候需要尽量使用内存的预分配,而少使用或者不使用数组内存空间的自动扩充方式。MATLAB针对不同的数据类型有不同的内存预分配函数,见表4-1。第四章 MATLAB编程基础 表表4-1 内存预分配函数内存预分配函数 第四章 MATLAB编程基础 表4-1中说明了不同数据类型所要使

32、用的内存预分配函数,其中结构类型的数组需要两个函数配合使用,利用struct函数构造结构,而使用repmat函数创建数组。对于非双精度类型的数据,例如整数类型或者单精度类型,进行内存的预分配时,需要使用相应的构造函数或者类型转换函数,例如:Y=int16(zeros(1:10000);在上面的表达式中创建了连续的10000个16位整数的存储空间。当预先分配的内存空间无法容纳数据时,则可以通过repmat函数来扩充数组的存储空间。第四章 MATLAB编程基础 3MATLAB加速器加速器尽管利用了上述的特性可以明显提高M语言的运行效率,但是在同等条件下,M语言的效率还是无法和第四代高级编程语言的执

33、行效率相媲美,于是,在MATLAB6.5版本中,新增加了MATLAB性能加速器这样一个新特性。MATLAB性能加速器能够明显改善循环结构、内建函数调用等方面的运行效率,特别是在处理循环迭代次数确定的for循环结构中,其运算速度较早期的MATLAB版本有很大的提高,在表4-2中总结了MATLAB加速器能够发挥作用的M语言元素。第四章 MATLAB编程基础 表表4-2 加速器能够影响的加速器能够影响的M语言元素语言元素 第四章 MATLAB编程基础 表表4-3 性能加速器不起作用的性能加速器不起作用的M语言元素语言元素 第四章 MATLAB编程基础 例子例子4-12性能加速器说明jitaccel.

34、m。001tic002A=rand(500000,1);003B=zeros(500000,1);004B(1)=A(1);005fori=2:500000006B(i)=B(i?1)+A(i);007end008toc第四章 MATLAB编程基础 在MATLAB6.1中:jitaccelelapsed_time=5.2780在MATLAB6.5中:jitaccelelapsed_time=0.0900若直接使用内建函数,则运行的效果为tic;B=cumsum(A,1);tocelapsed_time=0.0200第四章 MATLAB编程基础 通过比较,可以看出MATLAB性能加速器明显提高了

35、程序的执行效率,在有些情况下,加速器使执行速度提高10100倍。注意:例子4-12代码运算得到的时间和具体运行MATLAB的计算机的性能有关,不同的计算机环境得到的计算结果不尽相同。另外,MATLAB性能加速器在MATLAB6.5中的默认设置为开启(On)状态。第四章 MATLAB编程基础 4.3 脚脚 本本 文文 件件 脚本文件是最简单的一种M语言文件,在本章前面章节的例子中都使用了脚本文件。所谓脚本文件,就是由一系列的MATLAB指令和命令组成的纯文本格式的M文件,执行脚本文件时,文件中的指令或者命令按照出现在脚本文件中的顺序依次执行。脚本文件没有输入参数,也没有输出参数,执行起来就像早期

36、的DOS操作系统的批处理文件一样,而脚本文件处理的数据或者变量必须在MATLAB的公共工作空间中。第四章 MATLAB编程基础 例子例子4-13脚本文件示例。001%注释行002%M脚本文件示例003%flowerpetal004%以下为代码行005%计算006theta=-pi:0.01:pi;007rho(1,:)=2*sin(5*theta).2;008rho(2,:)=cos(10*theta).3;009rho(3,:)=sin(theta).2;010rho(4,:)=5*cos(3.5*theta).3;第四章 MATLAB编程基础 011fork=1:4012%图形输出013s

37、ubplot(2,2,k)014polar(theta,rho(k,:)015end016disp(程序运行结束!)在MATLAB命令行中运行该脚本文件:script_example程序运行结束!第四章 MATLAB编程基础 图4-2例子4-13脚本文件的运行结果第四章 MATLAB编程基础 仔细察看例子4-13的脚本文件,在脚本文件中,主要由注释行和代码行组成。M文件的注释行需要使用%定义符,在%之后的所有文本都认为是注释文本,不过,M文件的注释定义符仅能影响一行代码,类似于C+语言中的“/”。然而在M语言中,没有类似C语言的注释定义符“/*”和“*/”,所以无法一次定义多行注释。给程序添加

38、适当的注释是良好的编程习惯,希望读者能够在日常编程中多多使用。第四章 MATLAB编程基础 脚本文件中的代码行都是一些简单的MATLAB指令或者命令,这些命令可以用来完成相应的计算处理数据、绘制图形结果的操作,也可以在脚本文件中调用其他的函数完成复杂的数学运算,在例子4-13中就完成了这些工作。另外,在MATLAB中还有一些指令用来处理程序和用户之间的交互,在表4-4中进行了总结。第四章 MATLAB编程基础 表表4-4 脚本文件中常用的脚本文件中常用的MATLAB指令指令 第四章 MATLAB编程基础 MATLAB一般使用脚本文件作为某种批处理文件,其中,有两个批处理文件经常被MATLAB自

39、动调用,这两个脚本文件分别为startup.m和finish.m。startup.m文件在MATLAB启动时自动被执行,用户可以自己创建并定义编写该文件,例如在文件中添加物理常量的定义、系统变量的设置或者MATLAB搜索路径的设置。当用户安装MATLAB之后,在toolboxlocal路径下有一个M文件,名为Starupsav.m,该文件可以看作是startup.m文件的模板,可以修改该文件,然后将其以文件名startup.m的形式保存在toolboxlocal路径下。第四章 MATLAB编程基础 与startup.m文件相对应的是finish.m文件,该文件在MATLAB退出时自动执行,用户

40、可以自己创建并定义编写该文件,例如在文件中添加保存数据等指令,这样可以将每次退出前的工作结果进行保留。同样,在toolboxlocal路径下有两个文件,分别为finishsav.m和finishdlg.m,这两个文件可以用来作为finish.m文件的模板,相关的具体内容介绍请读者自己察看相应的文件和帮助文档。第四章 MATLAB编程基础 4.4 函函 数数 文文 件件 4.4.1 基本结构基本结构M函数文件和脚本文件不同,函数文件不仅有自己特殊的文件格式,不同的函数还分别具有自己的工作空间。同其他高级语言类似,M函数文件也有局部变量和全局变量。读者首先需要了解的是函数文件的基本结构,参见例子4

41、-14。第四章 MATLAB编程基础 例子例子4-14函数文件示例average.m。001functiony=average(x)002%AVERAGE求向量元素的均值003%语法:004%Y=average(X)005%其中,X是向量,Y为计算得到向量元素的均值006%若输入参数为非向量则出错007008%代码行009m,n=size(x);010%判断输入参数是否为向量第四章 MATLAB编程基础 011if(m=1)|(n=1)|(m=1&n=1)012%若输入参数不是向量,则出错013error(Inputmustbeavector)014end015%计算向量元素的均值016y=s

42、um(x)/length(x);第四章 MATLAB编程基础 在MATLAB命令行中,键入下面的指令运行例子4-14的代码:z=1:99;y=average(z)y=50第四章 MATLAB编程基础 M语言函数文件具有下面的不同部分:*函数定义行。*在线帮助。*注释行。*M语言代码。第四章 MATLAB编程基础 下面结合例子4-14分别说明这些部分的构成。函数定义行,例子4-14的函数定义行为代码的001行:001functiony=average(x)第四章 MATLAB编程基础 这一行代码中包括关键字function、函数输出参数y、函数的名称average和函数的输入参数x。需要读者注意

43、的是函数的名称,函数的名称定义要求必须以字符开头,后面可以用字符、数字和下划线的组合构成函数名称。MATLAB对函数名称的长度 有 限 定 , 读 者 可 以 在 自 己 的 MATLAB中 , 通 过 执 行namelengthmax函数获取相应的数值。假设该函数返回的数值为N,若函数的名称长度超过了N,则MATLAB使用函数名称的前N个字符作为函数名称。一般推荐将函数名称用小写的英文字符表示,同时函数的M文件名称最好和函数名称保持一致,若文件名称和函数名称不一致,则调用函数的时候需要使用文件名称而非函数名称。第四章 MATLAB编程基础 M函数文件的在线帮助为紧随在函数定义行的注释行。在例

44、子4-14中,average函数的在线帮助为002006行的注释行。若在MATLAB命令行中键入下面的指令:helpaverage在MATLAB的命令窗口中就会出现:AVERAGE求向量元素的均值语法:Y=average(X)其中,X是向量,Y为计算得到向量元素的均值若输入参数为非向量则出错第四章 MATLAB编程基础 其中,在线帮助中比较重要而且特殊的是在线帮助的第一行,在MATLAB中将这行注释称为H1帮助行,它是在线帮助的第一行,若使用lookfor函数查询函数时,仅查询并显示函数的H1帮助行,例如,在MATLAB命令行中键入下面的指令:lookforaverage在MATLAB的命令窗

45、口中就会出现:AVERAGE求向量元素的均值MEANAverageormeanvalue.第四章 MATLAB编程基础 由于H1帮助行的特殊作用,所以在用户自己定义M函数文件时,一定要编写相应的H1帮助行,对函数进行简明、扼要的说明或者解释。例子4-14的008、010、012、015行代码分别是程序具体的注释行,这些注释行不会显示在在线帮助中,主要原因就是这些注释行没有紧随在H1帮助行的后面,其中008行的注释与在线帮助之间有一个空行。其实从008行开始一直到文件的结尾都是M函数文件的代码行,这些代码行需要完成具体的算法,实现用户的具体功能。代码行就是用户开发的算法M语言的实现。第四章 MA

46、TLAB编程基础 4.4.2 输入输出参数输入输出参数M语言函数文件的输入、输出参数和其他高级语言的输入、输出参数不同,在定义这些输入、输出参数的时候不需要指出变量的类型,因为MATLAB默认这些参数都使用双精度类型,这样可以简化程序的编写。而且在定义参数时,也没有确定输入参数的维数或者尺寸,也就是说,直接从参数上无法判断输入来的是标量、向量还是矩阵,只有通过程序内部的具体代码来加以判断。M语言的函数文件不仅可以有一个输入参数和一个返回值,还可以为M语言函数文件定义多个输入参数和多个输出参数,见例子4-15。第四章 MATLAB编程基础 例子例子4-15多个输入、输出参数的M函数。001fun

47、ctionavg,stdev,r=ourstats(x,tol)002%OURSTATS多输入输出参数示例003%该函数计算处理矩阵,得到相应的均值、004%标准差和矩阵的秩005m,n=size(x);006ifm=1007m=n;008end009%Average010avg=sum(x)/m;第四章 MATLAB编程基础 011%Sandaddeviation012stdev=sqrt(sum(x.2)/m-avg.2);013%Rank014s=svd(x);015r=sum(stol);运行例子4-15,在MATLAB命令行中,键入下面的指令:A=123;456A=123456第四章

48、 MATLAB编程基础 a,s,r=ourstats(A,0.1)a=2.50003.50004.5000s=1.50001.50001.5000r=2ourstats(A,0.1)ans=2.50003.50004.5000a,s=ourstats(A,0.1)a=2.50003.50004.5000s=1.50001.50001.5000第四章 MATLAB编程基础 例子4-15的M代码具有两个输入参数、三个输出参数,所以在使用该函数的时候,需要将必要的输入、输出参数写明。注意调用该函数时的语法,将输出参数依次写在一个向量中,若输出参数的个数与函数定义的输出参数个数不一致,则在例子4-15

49、中,将计算得到的前几个输出参数作为返回值,个数等于用户指定的输出参数个数。计算的结果依次赋值给不同的变量。在使用多个输入、输出参数的时候,往往需要判断用户写明的输入、输出参数的个数,若个数与函数定义不符合的时候,将给出错误或者警告信息,这个时候,需要使用函数nargin和nargout来获取函数的输入、输出参数个数,见例子4-16。第四章 MATLAB编程基础 例子4-16nargin和nargout示例。001functionc=testarg(a,b)002%TESTARG检测输入输出参数个数003%该函数根据不同的输入输出参数个004%数进行相应的操作005if(nargout=1)00

50、6disp(使用该函数必须指定一个输出参数!);007return008end009switchnargin010case0第四章 MATLAB编程基础 011disp(使用该函数至少需要一个输入参数!);012c=;013return014case1015c=a.2;016case2017c=a+b;018end第四章 MATLAB编程基础 运行例子4-16,在MATLAB命令行窗口中,键入下面的指令:A=123;B=235;testarg(A,B)使用该函数必须指定一个输出参数!C=testarg使用该函数至少需要一个输入参数!C=C=testarg(A)C=149第四章 MATLAB编程

51、基础 C=testarg(A,B)C=358C=testarg(A,B,C)?Errorusing=testargToomanyinputarguments.第四章 MATLAB编程基础 运行例子4-16的代码时,使用不同的输入、输出参数,函数本身和MATLAB系统将自动检测参数的个数,在最后一次调用时,由于使用的输入参数个数超过了函数定义的个数,所以MATLAB给出了错误信息。MATLAB的M函数文件还可以具有个数不确定的输入、输出参数,也就是说,在定义M函数文件的时候,不指明输入、输出参数的个数,而是在程序中通过编写程序完成具体参数的确定,完成该功能主要依靠varargin和varargo

52、ut函数。第四章 MATLAB编程基础 当函数的定义具有以下形式的时候functiony=function_name(varargin)函数function_name可以接受任意个数的输入参数;而当函数具有下面的形式时functionvarargout=function_name(n)函数function_name可以输出任意个数的输出参数。可以将varargin函数和varargout函数结合在同一个M文件函数中使用。第四章 MATLAB编程基础 例子例子4-17不确定的输入参数个数。001functiony=varargin_example(varargin)002%VARARGIN_EX

53、AMPLE不确定输入参数例子003str=sprintf(输入参数的个数:=%d,length(varargin);004disp(str);005y=0;006%varargin的类型007class(varargin)008fori=1:length(varargin)009%varargin为元胞数组第四章 MATLAB编程基础 010if(isnumeric(varargini)011%将每个为数值数组的输入参数012%的第一个元素累加求和013y=y+varargini(1);014end015end第四章 MATLAB编程基础 运行例子4-17,在MATLAB命令行中键入下面的指令

54、:varargin_example输入参数的个数:=0ans=cellans=0varargin_example(a,123,3,rand(2,5)输入参数的个数:=4ans=cellans=4.0153第四章 MATLAB编程基础 通过例子4-17的运行结果和例子的代码可以看出varargin函数的使用方法。它相当于在MATLAB的函数入口处开辟了足够大的空间,用于接受各种用户的输入。在使用这个函数的时候,需要在程序中判别函数输入参数的类别,并且从元胞数组中正确提取变量,在MATLAB中将这一过程称之为unpacking。与之相对应的,将函数的输入参数传递给varargout函数被称之为pa

55、cking,在这一过程中,需要将所有必要的输出参数传递给varargout元胞数组,在传递参数的时候,还需要注意参数的顺序,在例子4-18中介绍了这一过程。第四章 MATLAB编程基础 例子例子4-18不确定的输出参数。001functionvarargout=varargout_example(varargin)002%VARARGOUT_EXAMPLE不确定个数的输出参数003004%判断输出参数的个数005%下面注释行中的代码执行有错误006%str=sprintf(输出参数的个数:=%d,length(varargout);007%必须使用nargout008str=sprintf(输

56、出参数的个数:=%d,nargout);009disp(str);010if(nargoutab=varargout_example(1,2,3,4)输出参数的个数:=2a=4b=3第四章 MATLAB编程基础 例子4-18的第006行代码,若将注释行符号“%”删除,则程序运行会出现错误。在程序中,若需要判断输出参数的个数不能使用length函数,而需要使用nargout函数。另外,在操作输出参数时,需要判断输出参数的个数,根据输出参数的个数完成相应的操作。在使用不确定的输入、输出参数时,还可以像下面的代码行一样使用这两个参数:functionout1,out2=example1(a,b,va

57、rargin)functioni,j,varargout=example2(x1,y1,x2,y2,flag)若使用varargout和varargin参数,除了必须给定的参数以外,其余的参数是任意数量可变的,具体的操作参阅例子4-19。第四章 MATLAB编程基础 例子4-19可变的输入、输出参数。001functionx,y,varargout=vararginout(a,b,c,d,varargin)002%VARARGINOUT可变的输入输出参数003str=sprintf(输入参数的个数:=%d,nargin);004disp(str);005str=sprintf(输出参数的个数:

58、=%d,nargout);006disp(str);007if(nargin2&nargin4)014for(i=1:nargout-2)015%这里也许会出错,小心!016varargouti=vararginend-i-1;017end018end第四章 MATLAB编程基础 运行例子4-19的代码,在MATLAB命令行中,键入下面的指令:vararginout(1,2,3,4,5)输入参数的个数:=5输出参数的个数:=0ans=10a,b,c=vararginout(1,2,3,4,5,6,7,8)输入参数的个数:=8输出参数的个数:=3a=10b=-2c=6第四章 MATLAB编程基础

59、 4.4.3 子函数和私有函数子函数和私有函数同一个M函数文件中可以包含多个函数。如果在同一个M函数文件中包含了多个函数,那么将出现在文件中的第一个M函数称为主函数(primaryfunction),其余的函数称为子函数(subfunction)。M函数文件的名称一般与主函数的名称保持一致,其他函数都必须按照函数的基本结构来书写,每一个函数的开始都是函数定义行,函数的结尾是另一个函数的定义行的开始或者整个M文件的结尾(最后一个子函数的结尾就是文件结束符)。不过,子函数不像主函数,一般子函数没有在线帮助,子函数的作用范围有限,它只能被那些在定义子函数的M文件中定义的函数(包括主函数和其他子函数)

60、调用,不能被其他M文件定义的函数调用。第四章 MATLAB编程基础 例子4-20子函数应用例子。001functionavg,med=newstats(u)%主函数002%NEWSTATS计算均值和中间值003n=length(u);004avg=mean(u,n);%调用子函数005med=median(u,n); %调用子函数006007functiona=mean(v,n)%子函数008%计算平均值009a=sum(v)/n;010第四章 MATLAB编程基础 011functionm=median(v,n)%子函数012%计算中间值013w=sort(v);014ifrem(n,2)=

61、1015m=w(n+1)/2);016else017m=(w(n/2)+w(n/2+1)/2;018end第四章 MATLAB编程基础 运行例子4-20,在MATALB命令行窗口中,键入下面的指令:x=1:11;mean,mid=newstats(x)mean=6mid=6第四章 MATLAB编程基础 在MATLAB中有一类函数被称为私有函数,这类函数被放置在名称为private的子目录中。每一个函数文件都是标准的M语言函数文件,没有特殊的关键字。但是,这些函数仅能被那些位于private子目录的上一层目录中的函数调用。例如,假设在MATLAB的搜索路径中包含路径ProjectA,那么所有位于

62、ProjectAprivate路径下的函数,只能在其上一层路径ProjectA中的函数文件中调用。由于私有函数作用范围的特殊性,不同父路径下的私有函数可以使用相同的函数名。由于MATLAB搜索函数时优先搜索私有函数,所以如果同时存在私有函数名func1.m和非私有函数名func1.m,则私有函数func1.m被优先执行。创建私有函数的方法非常简单,只要将那些需要设置为私有的函数都拷贝到一个private子目录中,则这些函数就能被那些位于父层目录中的M函数调用了。第四章 MATLAB编程基础 在表4-4中总结了子函数和私有函数的区别。表表4-4 私有函数和子函数比较私有函数和子函数比较 第四章

63、MATLAB编程基础 例子例子4-21私有函数的例子。创建一个新的函数文件,代码如下:001functionx=pmean(v,n)002%MEAN私有函数例子003%将该函数文件保存在pivae子目录中,004%则该函数仅能在上层目录的函数文件005%中调用006disp(私有函数mean);007x=sum(v)/n;第四章 MATLAB编程基础 图4-3将pmean.m文件保存在private目录下第四章 MATLAB编程基础 接着,修改newstats函数,并将其另存为newstats1.m。001functionavg,med=newstats1(u)%主函数002%NEWSTATS

64、计算均值和中间值003n=length(u);004avg=mean(u,n);%调用子函数005avg1=pmean(u,n)%调用私有函数006med=median(u,n); %调用子函数007008functiona=mean(v,n)%子函数009%计算平均值010disp(子函数mean);011a=sum(v)/n;012.第四章 MATLAB编程基础 然后在MATLAB命令行中,执行newstats1.m函数:newstats1(1:10);子函数meanavg= 5.5000私有函数meanavg1= 5.5000第四章 MATLAB编程基础 4.4.4 局部变量和全局变量局

65、部变量和全局变量同C语言类似,在M语言函数中也存在局部变量和全局变量。所谓局部变量,就是那些在M函数内部声明并使用的变量。这些变量仅能在函数调用执行期间被使用,一旦函数结束运行,则这些变量占用的内存空间将自动被释放,变量的数值也就不存在了。这是由于MATLAB的解释器在解释执行函数的时候,为不同的函数创建不同的工作空间,函数彼此的工作空间相互独立,一旦函数执行完毕,则函数的工作空间就不存在了。在本章前面的例子中,每个例子的函数内部声明使用的变量都是局部变量,所以函数执行完毕后,MATLAB的基本工作空间中没有这些变量存在,参见例子4-22。第四章 MATLAB编程基础 例子例子4-22局部变量

66、的例子。001functionlocal002%LOCAL察看局部变量的例子003x=rand(2,2);004y=zeros(2,2);005z=函数中的变量;006u=x,y,z;007disp(z)008whos第四章 MATLAB编程基础 运行例子4-22,在MATLAB命令行中,键入下面的指令:local函数中的变量Name SizeBytesClassu1x3256cellarrayx2x232doublearrayy2x232doublearrayz1x612chararrayGrandtotalis31elementsusing332byteswhos第四章 MATLAB编程基

67、础 通过运行local函数可以看到,所有在函数中创建的变量在函数运行结束后就不存在了。也就是说,局部变量的生存周期仅在函数的活动期间内。与局部变量相对应的就是全局变量。MATLAB将全局变量保存在特殊的工作空间进行统一维护、管理,而将变量声明为全局变量的方法就是在使用变量前,用关键字global声明,例如声明全局变量gXY:globalgXYwhosName SizeBytesClassgXY0x00doublearray(global)Grandtotalis0elementsusing0bytes第四章 MATLAB编程基础 需要强调一点,MATLAB管理、维护全局变量和局部变量使用了不同

68、的工作空间,所以使用global关键字创建全局变量的时候有三种情况:(1)若声明为全局的变量在当前的工作空间和全局工作空间都不存在,则创建一个新的变量,然后为这个变量赋值为空数组,该变量同时存在于局部工作空间和全局工作空间。(2)若声明为全局的变量已经存在于全局工作空间中,则不会在全局工作空间创建新的变量,其数值同时赋值给局部工作空间中的变量。(3)若声明为全局的变量存在于局部工作空间中,而全局工作空间不存在,则系统会提示一个警告信息,同时将局部的变量“挪”到全局工作空间中。第四章 MATLAB编程基础 例子例子4-23全局变量的例子。在MATLAB命令行窗口中,键入下面的指令:%创建全局变量

69、并赋值globalmyxmyx=10;%变量的信息whosNameSizeBytesClassmyx1x18doublearray(global)Grandtotalis1elementusing8bytes第四章 MATLAB编程基础 %清除变量clearmyx%察看信息whoswhosglobalNameSizeBytesClassmyx1x18doublearray(global)Grandtotalis1elementusing8bytes%在局部工作空间再次创建变量myx=23myx=23%变量的信息第四章 MATLAB编程基础 whosNameSizeBytesClassmyx1x

70、18doublearrayGrandtotalis1elementusing8bytes%将其修改为全局变量(注意警告信息)globalmyxWarning:Thevalueoflocalvariablesmayhavebeenchangedtomatchtheglobals.FutureversionsofMATLABwillrequirethatyoudeclareavariabletobeglobalbeforeyouusethatvariable.%看看变量的数值myxmyx=10第四章 MATLAB编程基础 %清除当前的工作空间clearwhosglobalNameSizeBytes

71、Classmyx1x18doublearray(global)Grandtotalis1elementusing8bytes%清除所有的内存空间clearallwhosglobal第四章 MATLAB编程基础 使用全局变量时,需要小心留意,因为全局变量可以在任何的函数中进行读写,这样,可能在比较复杂的程序中查找全局变量错误的时候就非常的麻烦。在MATLAB中还有一类变量被声明为persistent,本书将其称之为保留变量,这类变量类似于C语言函数中被声明为static类型的变量。这类变量在函数退出的时候不被释放,当函数再一次被调用的时候,这些变量保留上次函数退出时的数值。被声明为persist

72、ent的变量具有以下特征:*变量仅能在声明变量的函数内使用,其他函数不能直接使用这些变量。*函数执行退出后,MATLAB不清除这些变量占用的内存。*当函数被清除或者重新编辑后,保留的变量被清除。第四章 MATLAB编程基础 例子4-24persistent关键字。001functiony=persistent_example(x)002%PERSISTENT_EXAMPLE保留变量使用示例003fori=1:x004y=myfun;005end006007functiony=myfun008%子函数009%persistent关键字的使用010persistentcount;第四章 MATLA

73、B编程基础 011%count记录函数调用的次数012if(isempty(count)013count=1;014else015count=count+1;016end017str=sprintf(第%d次调用该函数,count);018disp(str);019y=count;第四章 MATLAB编程基础 在MATLAB命令行窗口中,执行该函数:persistent_example(2)第1次调用该函数第2次调用该函数ans=2persistent_example(3)第3次调用该函数第4次调用该函数第5次调用该函数ans=5第四章 MATLAB编程基础 从例子4-24的执行情况可以看出变

74、量count记录了函数被调用的次数,如果在MATLAB命令行中键入如下指令:clearall则所有的变量都会被清除,此时再次执行例子4-24:persistent_example(3)第1次调用该函数第2次调用该函数第3次调用该函数ans=3count数值又重新计数了。第四章 MATLAB编程基础 由于使用全局变量有这样那样的危险性,所以建议读者尽量使用函数参数传递的方式来完成函数之间的数据共享,或者可以使用persistent关键字将必要的变量保护起来。另外,isglobal命令可以用来测试本地变量与全局工作区中的变量是否存在联系,该命令并不能判断全局工作区中是否存在该变量。如果全局工作区中

75、存在某个变量,但与本地工作区中的相应变量没有联系,isglobal函数返回值为0(假)。第四章 MATLAB编程基础 4.4.5 函数执行规则函数执行规则到这里,读者应该能够创建自己的算法函数,并且能够执行任何M语言函数了。只要在MATLAB的命令行窗口中键入函数的名称,并且提供足够的输入、输出参数就会得到正确的结果。如前文所述,M语言的函数被MATLAB的解释器解释、执行,所以,在本小节中将简要讨论一下解释器解释执行程序的问题。当用户在MATLAB命令行窗口键入一条命令或者执行M语言文件中包含的一条语句或者指令时,MATLAB解释器就负责解析用户的输入,并且给出相应的答案。MATLAB解释器

76、解析命令按照一定优先级进行:第四章 MATLAB编程基础 *首先判断输入的命令是否为变量。*若不是内存中的变量,判断输入的命令是否为MATLAB的内建函数。*若不是内建函数,则判断输入的命令是否为子函数。*若不是子函数,则判断输入的命令是否为私有函数。*若不是私有函数,则判断输入的命令是否为MATLAB搜索路径中所包含的某个文件或函数。*若在同一个路径下发现同名的三种类型的文件MEX文件、P代码文件和M代码文件,则优先执行MEX文件,其次是P代码文件,最后执行的是M语言文件。第四章 MATLAB编程基础 提示:若需要了解具体调用的是哪一个对象,则可以使用which命令获取相应的信息。这里需要注

77、意的一点就是,MATLAB内存中的变量比函数具有较高的优先级,如例子4-25所示。第四章 MATLAB编程基础 例子例子4-25MATLAB命令解析的优先级。在MATLAB命令行窗口中,键入下面的指令:cos=Thisisastring!cos=Thisisastring!cos(4)ans=swhichcoscosisavariable.第四章 MATLAB编程基础 clearallcos(4)ans=-0.6536whichcoscosisabuilt-infunction.通过例子4-25说明,MATLAB命令解释器在解释、执行MATLAB指令时,将变量置于第一位,所以读者在进行M语言编

78、程的时候注意自己定义的变量名称,避免命名冲突。第四章 MATLAB编程基础 提示:P代码(伪代码)文件是从M文件用pcode命令生成的。伪代码是经过预编译的,无论何时函数被调用,MATLAB都能访问的现成代码。因为P文件是预编译过的,所以它们的实际内容对用户而言是不可读的,而且在一般情况下它们比相应的M文件运行速度快。将M语言函数文件转变为P代码文件的方法是pcodefun1fun2.MEX文件是一种特殊的文件格式,主要使用C语言进行开发,并且经过编译后在MATLAB环境中使用,关于MEX文件的详细信息将在MATLAB外部接口编程一书中详细讨论。第四章 MATLAB编程基础 4.5 M 文文

79、件件 调调 试试 M语言文件的编辑器meditor不仅仅是一个文件编辑器,同时还是一个可视化的调试开发环境。在M文件编辑器中可以对M脚本文件、函数文件进行调试,以排查程序的错误。M文件的调试不仅可以在文件编辑器中进行,而且还可以在命令行中结合具体的命令进行,但是过程相对麻烦一些,所以本小节将重点讲述在M文件编辑器中进行可视化调试的过程。一般地来说,应用程序的错误有两类,一类是语法错误,另外一类是运行时的错误。其中,语法错误包括了词法或者文法的错误,例如函数名称的拼写错误等。而运行时的错误是指那些程序运行过程中得到的结果不是用户需要的情况。但是,由于M文件是一种解释型语言,语法错误和运行时的错误

80、都只有在运行过程中才能发现,所以程序的调试往往是在程序无法得到正确结果时进行程序修正的惟一手段。第四章 MATLAB编程基础 为了能够有效地处理各种情况,M语言的断点类型除了类似C语言的用户定义的断点外,还有几种自动断点,分别为*StopifError。*StopifWarning。*StopifNaNorInf。*StopifAllErrors。这些自动断点可以在程序中设置,当程序运行过程中发生了错误或者警告,则程序运行中断,进入调试状态。第四章 MATLAB编程基础 图4-4M文件编辑器的Breakpoints菜单第四章 MATLAB编程基础 例子例子4-26M文件调试代码stats_er

81、ror.m。001functiontotalsum,average=stats_error(input_vector)002%STATS_ERROR-Calculatescumulativetotal&average003totalsum=sum(input_vector);004average=ourmean(input_vector);005006functiony=ourmean(x)007%OURMEAN-Calculatesaverage008m,n=size(x);009ifm=1010m=n;011end012y=sum(input_vector)/m;第四章 MATLAB编程基

82、础 首先在MATLAB环境中启动M文件编辑器,然后选择M文件编辑器中“Breakpoints”菜单下的“StopifError”命令。注意,这时不一定需要将stats_error.m文件在文件编辑器中打开。然后,在MATLAB命令行窗口中键入下面的指令:sumavg=stats_error(rand(1,50)?Undefinedfunctionorvariableinput_vector.Errorin=D:TEMPch4stats_error.m(ourmean)Online12=y=sum(input_vector)/m;第四章 MATLAB编程基础 图4-5处于调试状态的M文件编辑器第

83、四章 MATLAB编程基础 在M文件编辑器中,第12行代码前有绿色的箭头,表示当前程序运行在此处中断。通过用户界面中的Stack下拉框可以察看当前应用程序使用堆栈的状态,如本例子中Stack下拉框中包含如下的内容:ourmean、stats_error和Base,由下至上,分别为调用者和被调用者之间的关系,同时也显示了当前的工作空间。另外,部分按钮从编辑状态进入调试状态,如图4-6所示。这些按钮分别执行增加断点、清除断点、单步执行等调试程序的功能。将鼠标光标移动到按钮处并保持几秒钟,MATLAB的文件编辑能够给出相应的提示。第四章 MATLAB编程基础 图4-6调试程序的按钮第四章 MATLA

84、B编程基础 此时,MATLAB命令行窗口也处于调试状态,在这种状态下命令行提示符为“K”,在该命令行提示符中可以任意键入MATLAB指令进行运算和处理,不过需要注意,此时的工作空间是函数正在应用的空间,若在命令行窗口中键入的指令影响了工作空间中的变量,则可以直接影响程序运行的结果。例如,在当前的提示符“K”键入下面的指令:KwhosNameSizeBytesClassm1x18doublearrayn1x18doublearrayx 1x50400doublearrayGrandtotalis52elementsusing416bytes第四章 MATLAB编程基础 可以看到,当前的工作空间下

85、没有变量名input_vector,这也是该程序执行出错的原因,将程序中第12行的input_vector修改成为x就能得到正确的答案了。MATLAB可视化程序调试功能相对于VisualC+的可视化调试功能弱了一些,但是,在调试程序的过程中通过MATLAB命令行窗口的配合,充分利用MATLAB命令行窗口“演算纸”的功能,能够非常方便地调试M语言应用程序。另外,MATLAB也提供了一些指令用于进行M文件的调试,在表4-5中对这些命令进行了总结。第四章 MATLAB编程基础 表表4-5 应用与调试应用与调试M文件的指令文件的指令第四章 MATLAB编程基础 表4-5中指令的具体使用方法请读者查阅在

86、线帮助或者MATLAB的帮助文档,在本书中就不再赘述了。其中,比较常用的指令是dbquit,在可视化调试过程中,往往会出现没有退出调试状态就关闭了M文件编辑器的情况,这时可以在“K”提示符下键入该指令退出调试状态。另外,在startup.m文件中利用dbstop指令预先设置自动断点为有效,这样就不必每次在调试应用程序前设置自动断点了。第四章 MATLAB编程基础 4.6 M文件性能分析文件性能分析使用M文件性能分析器有两种方法,其中一种方法是通过命令行,另外一种方法是通过图形用户界面。本小节分别介绍这两种使用M文件性能分析器的方法。本小节用来分析的程序为例子4-10 向量化运算array_vs

87、_loops.m的代码。使用性能分析器的图形用户界面,通过执行MATLAB的“Start”菜单中“MATLAB”子菜单下的“Profiler”命令,得到性能分析器的用户界面,如图4-7所示。第四章 MATLAB编程基础 图4-7性能分析器的图形用户界面第四章 MATLAB编程基础 图4-8性能分析的总结报告第四章 MATLAB编程基础 图4-9性能分析的详细报告执行次数报告第四章 MATLAB编程基础 详细分析报告主要按照不同的项目统计了程序的执行,其中包括运行时间(Time)、语句调用次数(NumberofCall)、覆盖率(Coverage)、已加速的代码(Acceleration)。从分

88、析报告中就可以得出占用了较多计算处理时间的代码段或代码行。另外,通过性能分析器的报告也能看出使用数组运算大大提高了M文件的执行性能。读者进行到这里可以单击详细报告上的所有超链接,获取关于M文件的详细信息。第四章 MATLAB编程基础 这里比较重要的就是察看代码的加速信息了,在M语言文件性能分析器中,如果代码的前面具有“x”标识,则说明此行代码没有被MATLAB性能加速器加速,用户可以单击“x”标识,则性能分析器将弹出对话框说明此行代码没有被加速的具体原因。用户可以充分利用该对话框的提示信息修改代码,以提高程序的执行效率。第四章 MATLAB编程基础 注意:注意:由于系统的限制,截至笔者截稿前的

89、MATLAB最新版本,图形用户界面的性能分析器都不能处理任何包含中文字符的M文件代码。另外一种进行性能分析的方法是直接利用命令行的方式进行,这里主要用到一个函数profile,该函数的主要使用方法为profilekeywords其中,根据不同的关键字执行不同的功能,而使用的过程大体分为三个步骤:首先,在MATLAB命令行中键入下面的指令:profileon其中,关键字on的作用是开启性能分析器,并且将前面的统计结果清除。第四章 MATLAB编程基础 注意:当性能分析器处于开启状态时,MATLAB的状态栏显示“Profileon”。其次,运行需要分析的M文件,例如,本小节使用的array_vs_

90、loops.m文件。运行文件的方法和正常运行M文件的方法一致:array_vs_loops第三步,也就是最后一步,在MATLAB命令行中键入下面的指令:profilereport这时MATLAB将分析的结果创建为一个超文本格式的文档,该文档就是性能分析的总结文档,如图4-10所示。第四章 MATLAB编程基础 图4-10性能分析结果第四章 MATLAB编程基础 通过单击相应的超链接可以获取相应文件的分析报告,其主要内容为每一行代码执行占用的时间。和使用图形用户界面的性能分析器相比较,这个分析报告的内容相对简单,只有执行时间的报告,但是能够支持包含中文的语句,如图4-11所示。第四章 MATLA

91、B编程基础 图4-11性能分析的详细报告第四章 MATLAB编程基础 表表4-6 profile函数的使用方法函数的使用方法 第四章 MATLAB编程基础 4.7 本本 章章 小小 结结 在本章主要讲述了关于如何利用MATLAB的编程语言M语言进行编程的方方面面。MATLAB提供了一种高级编程语言M语言,这种语言的语法结构与C语言非常类似,任何熟悉C语言的用户学习使用M语言都不会有任何障碍。尽管M语言是一种解释性的编程语言,但是随着MATLAB版本的不断升级,以及充分利用MATLAB提供的各种编程技巧,能够有效提高M语言应用程序的执行效率,使M语言成为了工程领域中最适合进行算法开发验证的编程语言。第四章 MATLAB编程基础 通过本章的学习之后,读者应该能够比较熟练地利用M语言实现自己的想法。MATLAB是灵活、可靠的开发环境,用户不仅可以利用已有的MATLAB的功能,而且还能够利用M语言丰富MATLAB的能力。通过本章的学习,读者还能够充分利用MATLAB新版本特性,以及MATLAB丰富的编程调试工具调试器和性能分析器,编写出高效率可靠的应用程序。本章所涉及的内容仅仅是M语言的一部分内容,请读者仔细阅读MATLAB的帮助文档,已获得更加全面的信息。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号