1、,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,2,第,*,页,MATLAB R2007,基础教程 清华大学出版社,2,第,1,页,第,7,章,MATLAB 2007,程序设计,MATLAB R2007,基础教程 清华大学出版社,教学目标,教学重点,教学内容,2,第,2,页,教学目标,熟悉,MATLAB,的编程环境,掌握,MATLAB,的变量类型,掌握,MATLAB,中的流程控制语句,掌握,MATLAB,的函数类型和函数操作,了解,MATLAB,中的错误处理,了解,MATLAB,程序调试方法,了解,MATLAB,代码优化方法,2,第,3,页,教学重点,MA
2、TLAB,的编程环境,MATLAB,的变量类型,MATLAB,中的流程控制语句,MATLAB,的函数类型和函数操作,MATLAB,程序调试方法,2,第,4,页,教学内容,M,文本文件介绍,函数流程控制,函数变量,函数类型,函数操作,MATLAB,编程错误处理,程序设计的辅助函数,调试程序,优化程序,2,第,5,页,M,文本文件介绍,一个,M,文件通常包含五个部分,函数定义语句、,H1,帮助行、帮助文本、函数体或者脚本文件语句和注释语句。,H1,行为紧随函数定义语句后面的一行注释语句。当用户通过,help,命令查询该函数的说明信息时,H1,行显示为第一行,另外,lookfor,函数只检索和显示,
3、H1,行。帮助文本为,H1,行后面连续的注释行,当在命令窗口中通过,help,命令查询该函数的说明信息时则在窗口中显示这些内容。函数体为,M,文件的主要部分,是函数的执行代码。除上面的,H1,行和帮助文本外,为了易于理解,可以在书写代码时添加注释语句。这些注释语句在编译程序时会被忽略,因此不会影响编译速度和程序运行速度,但是能够增加程序的可读性。,2,第,6,页,一个完整的,M,文件的结构为:,function f=fact(n),函数定义语句,%Compute a factorial value.H1,行,%FACT(N)returns the factorial of N,帮助文本,%us
4、ually denoted by N!,%Put simply,FACT(N)is PROD(1:N).,注释语句,f=prod(1:n);,函数体,函数定义语句只在函数文件中存在,定义函数名称、输入输出参数的数量和顺序。函数定义语句的格式为:,function y=fact(x),。,2,第,7,页,函数式,M,文件,函数式,M,文件比脚本式,M,文件相对复杂一些,脚本文件不需要自带参数,也不一定返回结果,而函数文件一般要自带参数,并且有返回结果,以便于更好的把整个程序连为一段。函数文件也可以不带参数,此时文件中一般使用一些全局变量来实现与外界和其他函数之间的数据交换。,函数文件的第一行以,
5、function,开始,说明此文件是一个函数。其实质为用户向,MATLAB,函数库中添加的子函数。在默认情况下,函数文件中的变量都是局部变量,仅在函数运行期间有效,函数运行结束后,这些变量将从工作区中清除。,2,第,8,页,函数流程控制,顺序结构,判断语句(,ifelseend,),分支语句,循环语句,trycatchend,语句,其他流程控制函数,2,第,9,页,顺序结构,顺序结构是最简单的程序结构,系统在编译程序时,按照程序的物理位置顺序执行。这种程序容易编制,但是结构单一,能够实现的功能有限。,2,第,10,页,判断语句(,ifelseend,),ifend,ifelseend,ifel
6、seifelseend,2,第,11,页,ifend,此时的程序结构如下:,if,表达式,执行代码块,end,这是最简单的判断语句,只有一个判断语句,其中的表达式为逻辑表达式,当表达式为真时,执行相应的语句,否则,直接跳到下一段语句。,2,第,12,页,ifelseend,当程序有两个选择时,可以选择,ifelseend,结构,此时程序结构为:,if,表达式,执行代码块,1,else,执行代码块,2,end,当判断表达式为真时,执行代码块,1,,否则执行代码块,2,。,2,第,13,页,ifelseifelseend,上面的两种形式中,分别包含一个选择和两个选择,当判断包含多个选择时,可以采用
7、,elseif,语句,结构为:,if,表达式,1,执行代码块,1,elseif,表达式,2,执行代码块,2,elseif.,.,.,else,执行代码块,end,其中可以包含任意多个,elseif,语句。,2,第,14,页,分支语句,上一节中的,ifelseifelseend,语句可以适用于多种选择的流程控制,此时对,else,之外的每一个选择语句设置一个表达式,表达式为真时则执行该模块。,MATLAB,中的另一种多选择语句为分支语句。分支语句的结构为:,switch,分支语句,case,条件语句,执行代码块,case,条件语句,1,条件语句,2,条件语句,3,.,执行代码块,otherwis
8、e,执行代码块,end,2,第,15,页,其中的分支语句为一个变量,可以是数值变量或者字符串变量,如果该变量的值与某一条件相符,则执行相应的语句,否则,执行,otherwise,后面的语句。在每一个条件中,可以包含一个条件语句,可以包含多个条件,当包含多个条件时,将条件以单元数组的形式表示。,MATLAB,的分支语句类似于,C,语言的分支语句,但是又不完全相同:,MATLAB,语句从上到下依次判断条件,条件符合则执行相应的代码块,之后退出该分支语句,因此在代码块后面不需要添加“,break”,语句。,2,第,16,页,循环语句,for,语句,while,语句,2,第,17,页,1,for,语句
9、,for,语句将相同的代码执行预定义的次数。,for,语句的结构为:,for,循环变量,=,表达式,执行代码块,end,for,循环的语句在前面的例子中已经有所涉及,上节的例子中,第二个程序中也涉及到了,for,循环语句。下面为,for,循环的更多例子。,2,第,18,页,2,while,语句,while,语句用于将相同的代码块执行多次,但是次数并不预先指定,当,while,的条件表达式为真时,执行代码块,直到条件表达式为假。,while,语句的结构为:,while,表达式,执行代码块,end,2,第,19,页,6.2.5 trycatchend,语句,MATLAB,中的另一种判断语句为,tr
10、ycatch,语句,这种语句可以包容程序运行中的错误,并返回错误类型。这种语句的结构为:,try,运行代码块,catch,运行代码块,end,该语句首先从上到下依次执行,如果遇到程序错误则运行下一个,catch,中的语句,依次向下进行。如果程序运行成功,则退出该判断语句。如果在,catch,和,end,之间的程序运行出错,则程序运行终止,或者如果存在其他的,trycatch,结构,则运行下一个,trycatch,结构。可以利用,lasterr,命令查看发生错误的原因。,2,第,20,页,6.2.6,其他流程控制函数,continue,:,continue,语句通常用在循环控制中,包括,for,
11、循环和,while,循环,用于结束当次循环,继续执行下一次循环,但是不结束当前循环。一般,continue,语句与,if,语句相结合,当满足一定的条件时,执行,continue,语句。,break,:与,continue,相同的是,,break,函数也是用于循环控制,中断当前循环。与,continue,不同,,break,跳出当前循环,不再执行该循环的任何操作。,return,:结束该程序的执行,返回到调用函数或者键盘。,2,第,21,页,6.3,函数变量,6.3.1,变量类型,局部变量,全局变量,永久变量,2,第,22,页,局部变量,每个函数都有自己的局部变量,这些变量存储在该函数独立的工作
12、区中,与其他函数的变量及主工作区中的变量分开存储。当函数调用结束时,这些变量随之删除,不保存在内存中。并且,除了函数返回值,该函数不改变工作区中其他变量的值。,然而脚本文件没有独立的工作区,当通过命令窗口调用脚本文件时,脚本文件分享主工作区,当函数调用脚本文件时,脚本文件分享主调函数的工作区。需要注意的是,如果脚本中改变了工作区中变量的值,则在脚本文件调用结束后,该变量的值发生改变。,在函数中,变量默认为局部变量。,2,第,23,页,全局变量,局部变量只在一个工作区内有效,无论是函数工作区还是,MATLAB,主工作区。与局部变量不同,全局变量可以在定义该变量的全部工作区中有效。当在一个工作区内
13、改变该变量的值时,该变量在其他工作区中的变量同时改变。,任何函数如果需要使用全局变量,则必须首先声明,声明格式为:,global,变量名,1,变量名,2,如果一个,M,文件中包含的子函数需要访问全局变量,则需在子函数中声明该变量,如果需要在命令行中访问该变量,则需在命令行中声明该变量。,2,第,24,页,永久变量,除局部变量和全局变量外,,MATLAB,中还有一种变量类型为永久变量。永久变量的特点为:,只能在,M,文件内部定义;,只有该变量从属的函数能够访问该变量;,当函数运行结束时,该变量的值保留在内存中,因此当该函数再次被调用时,可以再次利用这些变量。,永久变量的定义方法为:,persis
14、tent,变量名,1,变量名,2,。,2,第,25,页,6.4,函数类型,6.4.1,匿名函数,6.4.2,主函数,6.4.3,子函数,6.4.4,嵌套函数,6.4.5,私有函数,6.4.6,重载函数,2,第,26,页,匿名函数,关于匿名函数在前面“,MATLAB,的数学运算”一章中已有初步涉及,在“函数运算”一节的示例中用到了大量的匿名函数。本节对匿名函数做进一步的介绍。,匿名函数提供了一种创建简单程序的方法,使用它用户可以不必每次都编写,M,文件。用户可以在,MATLAB,的命令窗口或是其他任意,M,文件和脚本文件中使用匿名函数。,匿名函数的格式为:,fhandle=(arglist)ex
15、pr,其中,fhandle,是为该函数创建的函数句柄;,符号用于创建函数句柄;,arglist,为用逗号分隔的参数列表;,expr,为函数主体,为,MATLAB,表达式。,2,第,27,页,主函数,通常每个,M,文件中的第一个函数为主函数,主函数可以被该文件之外的其他函数调用,而子函数只能被该文件内的函数调用。主函数的调用通过存储该函数的,M,文件的文件名调用。我们在前面几节中编写的实验程序,大多为主函数,如例,6-7,。因此,这里不再过多介绍。,2,第,28,页,子函数,一个,M,文件中可以包括多个函数,除主函数之外的其他函数称为子函数。子函数只能被主函数或该文件内的其他子函数调用。每个子函
16、数以函数定义语句开头,直至下一个函数的定义或文件的结尾。,当函数中调用函数时,系统判断其函数类型的顺序为:首先判断是否为子函数,然后判断是否为私有函数,最后判断其是否为当前目录下的,M,文件函数或者系统内置函数。由于子函数具有最高的优先级别,因此,在定义子函数时,可以采用已有的其他外部函数的名称。,2,第,29,页,嵌套函数,一个函数内部可以定义其他的函数,这种内部的函数称作嵌套函数。,1,嵌套函数的书写,定义嵌套函数时,只要在一个函数内部直接定义嵌套函数即可。需要注意的是当一个,M,文件中存在嵌套函数时,该文件内的所有函数必须以,end,结尾。,2,第,30,页,例,6-14,嵌套函数的结构
17、,function x=A(p1,p2),.,function y=B(p3),.,end,.,end,2,第,31,页,每个函数中可以嵌套多个函数。,例,6-15,多个平行嵌套函数,function x=A(p1,p2),.,function y=B(p3),.,end,function z=C(p4),.,end,.,end,2,第,32,页,在这个程序中,函数,A,嵌套了函数,B,和函数,C,。另外,嵌套函数还可以包含嵌套函数,其结构如例,6-16,。,例,6-16,多层嵌套函数,function x=A(p1,p2),.,function y=B(p3),.,function z=C(
18、p4),.,end,.,end,.,End,在这段程序中,函数,A,嵌套了函数,B,,函数,B,嵌套了函数,C,。,2,第,33,页,2,嵌套函数的调用,一个嵌套函数可以被下列函数调用:,(,1,)该嵌套函数的上一层函数,如上面例,6-13,中函数,A,可以调用函数,B,,函数,B,可以调用函数,C,,但是函数,A,不能调用函数,C,;,(,2,)同一母函数下的同级嵌套函数,如上面例,6-12,中函数,B,可以调用函数,C,;,(,3,)被任一低级别的函数调用。,2,第,34,页,在这段程序中,函数,A,包含了嵌套函数,B,和嵌套函数,D,,函数,B,和函数,D,分别嵌套了函数,C,和函数,E
19、,。这段程序中函数间的调用关系为:,(,1,)函数,A,为主函数,可以调用函数,B,和函数,D,,但是不能调用函数,C,和函数,E,;,(,2,)函数,B,和函数,D,为一级嵌套函数,,B,可以调用函数,D,和函数,C,,但是不能调用函数,E,;,D,可以调用函数,B,和函数,E,,但是不能调用,C,;,(,3,)函数,C,和函数,E,为分属两个函数的嵌套函数,可以调用函数,B,和函数,D,,但是不能互相调用。,2,第,35,页,私有函数,私有函数是,MATLAB,中的另一类函数,这类函数位于名为“,private”,的子文件夹中,只能被上一级文件夹中的函数或者这些函数所调用的,M,文件调用。
20、如,当前文件夹为,matlabmath,,,matlabmath,中包含子文件夹,private,,则,private,中的函数只能被,matlabmath,根目录下的函数及这些函数调用的,M,文件调用。,私有函数只能被其父文件夹中的函数调用,因此,用户可以开发自己的函数库,函数的名称可以与系统标准,M,函数库名称相同,而不必担心在函数调用时发生冲突,因为,MATLAB,首先查找私有函数,再查找标准函数。,2,第,36,页,重载函数,函数重载为程序编写和用户调用都提供了很大的方便。函数重载允许多个函数使用相同的函数名,不同的输入参数类型。在函数调用时,系统根据输入参数的情况自动选择相应的函数执
21、行。,2,第,37,页,函数操作,函数句柄,利用函数句柄可以实现对函数的间接操作,可以通过将函数句柄传递给其他函数实现对函数的操作,也可以将函数句柄保存在变量中,留待以后调用操作。,函数句柄是通过,符号创建的,格式为:,fhandle=functionname,。,2,第,38,页,若要保存函数句柄,可以使用单元数组,如下:,trigFun=sin,cos,tan;,通过函数句柄实现对函数的间接调用,其调用格式与直接调用函数的格式相同:,fhandle(arg1,arg2,.,argn),,其中,fhandle,为函数句柄。,2,第,39,页,函数参数,当调用函数时,主调函数通过函数参数的形式
22、向被调函数传递数据,被调函数通过函数返回值的形式向主调函数返回数据。本节介绍函数参数,内容包括:输入参数数目确定、输入可变数目的参数、向嵌套函数输入可选参数和修改参数值并返回。,2,第,40,页,1,函数参数数目确定,函数,nargin,和函数,nargout,分别用于确定函数的输入输出参数个数。在函数体内部用,nargin,(,nargout,)确定输入输出参数后可以用条件语句确定需要执行的操作。,2,第,41,页,函数,nargin,和函数,nargout,允许函数接收或返回任意数目的参数。本节介绍参数数目可变的函数。,在,MATLAB,中,输入输出参数是以单元数组的形式进行传输的:输入参
23、数以单元数组的形式传递给函数,单元数组的每个元素为相应的参数,同样,输出参数也是以单元数组的形式组织的。如此的参数组织形式便于函数接受任意数目的参数。见下面的例子。,2,第,42,页,在调用该函数时可以输入任意数目的参数,参数可以为二元数组或者表示线型的字符串,该函数将用指定的线型绘制输入数据的图像。指定线型的字符串可以在任意位置输入,并且可以输入多个,但是需要注意的是,只有最后一个字符串起作用。,在上面的程序中,将所有输入参数作为一个单元数组,利用花括号和圆括号对数组元素进行访问,实现输入参数的调用。,2,第,43,页,在嵌套函数中也可以使用可变参数。但是需要注意的是,,varargin,、
24、,varargout,、,nargin,和,nargout,的意义可能有所不同。下面介绍这四个元素的应用规则。,varargin,和,varargout,这两个元素为变量,与,MATLAB,其他变量的作用范围相同。由于嵌套函数与主函数使用相同的工作区,因此,varargin,和,varargout,既可以表示嵌套函数的输入输出参数,也可以是主函数的输入输出函数,具体值取决于程序中的变量声明:,如果嵌套函数在函数声明中包含,varargin,或者,varargout,,则在该函数内部调用这两个变量时,变量内容为该函数的输入输出参数;,如果嵌套函数声明中没有包含,varargin,或者,varar
25、gout,,而在该函数的上层函数声明中包含,varargin,或者,varargout,,则当在该嵌套函数内部调用这两个变量时,变量内容为上层函数的输入输出参数。,2,第,44,页,nargin,和,nargout,nargin,和,nargout,是函数,当在函数中调用这两个函数时,其值为该函数的输入或输出参数,而不需要进行声明。如上面的例子中,在函数,A,中调用,nargin,(,B(nargin,y*rand(4),)表示函数,A,的输入参数个数,在函数,C,中调用,nargin,表示函数,C,的输入参数个数。,2,第,45,页,MATLAB,编程错误处理,通过,try-catch,语句
26、检测错误,对错误进行处理并且从错误中恢复,消息标志符,警告处理,2,第,46,页,通过,try-catch,语句检测错误,无论程序的编写多么谨慎,在不同的环境下运行时都有可能产生意外的错误。因此,有必要在程序中添加错误检测语句,保证程序在所有的条件下都能够正常运行。,MATLAB,中的,try-catch,语句可用于错误检测。如果程序中的一些语句可能会产生非预计的结果,可以将这些语句放在,try-catch,块中。,try-catch,语句可以检测所有错误,并且分别进行处理。格式如下:,try,表达式,1,catch,表达式,2,end,一个,try-catch,块分为两个部分。第一个部分以,
27、try,开始,第二个部分以,catch,开始,整个块以,end,结束。程序首先正常执行第一部分,如果有错误发生,则停止执行该部分的其他语句,转而执行,catch,中的语句。,catch,部分对错误进行处理,可以显示错误提示、执行默认语句等。,2,第,47,页,在,try-catch,语句中,可以嵌套其他的,try-catch,语句,其格式为:,try,表达式,1%,执行表达式,1,catch,try,表达式,2%,尝试从错误中恢复,catch,disp Operation failed%,处理错误,end,end,2,第,48,页,对错误进行处理并且从错误中恢复,1,发出错误报告,MATALB
28、,中,error,函数可以报告错误并且中断程序运行。用户可以通过指定,error,函数参数的方式指定将要发出的错误信息。,2,第,49,页,2,识别错误发生的原因,当错误发生时,用户需要知道错误发生的位置及错误原因,以便能够正确处理错误。,lasterror,函数可以返回最后发生的错误的相关信息,辅助用户识别错误。,lasterror,返回结果为一个结构体,该结构体包含三个域,分别为,message,、,identifier,、,stack,。,message,为字符串,起内容为最近发生的错误的相关文本信息;,identifier,也是一个字符串,内容为错误消息的类别标志;,stack,为一结
29、构体,其内容为该错误的堆栈中的相关信息。,stack,包含三个域,为,file,、,name,和,line,,分别为文件名、函数名和错误发生的行数。,2,第,50,页,3,错误重现,在一些情况下,需要重现已经抛出过的错误,以便于对错误进行分析。,MATLAB,中函数,rethrow,可以重新抛出指定的错误。该函数的格式为,rethrow(err),,其中输入参数,err,用于指定需要重现的错误。该语句执行后程序运行中断,将控制权转给键盘或,catch,语句的上一层模块。输入参数,err,需为,MATLAB,结构体,包含,message,、,identifier,、,stack,中至少一个域,这
30、三个域的类型与,lasterror,返回结果相同。,rethrow,函数通常与,try-catch,语句一起使用。如:,try,表达式,1,catch,do_cleanup,rethrow(lasterror),end,2,第,51,页,消息标志符,1,消息标志符的格式,标志符为一个字符串,指定错误或警告消息的类别(,component,)及详细信息(,mnemonic,)。通常为“类别,:,详细信息”的格式。如:,MATLAB:divideByZero,Simulink:actionNotTaken,TechCorp:notFoundInPath,等。两个部分都需要满足如下的规则:,(,1,
31、)不能包含空格,(,2,)第一个字符必须为字母,(,3,)后面的字符可以为数字或下划线,类别部分指定错误或警告可能发生的大体位置,通常为某一产品的名字或者工具箱的名字,如,MATLAB,或者,Control,。,MATLAB,支持使用多层次的类别名称。,详细信息用于指定消息的具体内容,如除数为,0,等。,如下面的例子为一个完整的标志符:,error(MATLAB:ambiguousSyntax,Syntax%s could be ambiguous.n,inputstr),。,2,第,52,页,2,标志符的应用,消息标志符通常与,lasterror,函数一起应用,使得,lasterror,函数
32、和,lasterr,函数能够识别错误的原因。,lasterror,函数和,lasterr,函数返回消息标志符,用户可以通过其类别信息和详细信息分别获取错误的总体类别及具体信息。,使用消息标志符的第一步为确定目的信息并为其指定标志符。消息标志符通过,error,函数指定,格式为:,error(msg_id,errormsg),error(msg_id,formatted_errormsg,arg1,arg2,.),其中的消息标志符可以省略。如果,lasterror,函数不使用该信息,上面的语句可以简写为:,error(errormsg),下面以两个实例说明消息标志符与,lasterror,的使用
33、。,2,第,53,页,函数,功能,catch,指定对,try,部分发生的错误做出如何的操作,error,显示错误消息并听出程序运行,ferror,获取文件输入输出中的错误信息,intwarning,返回整数警告的控制状态,lasterror,上一个错误的信息,rethrow,重新抛出上一个错误,try,试图运行一个代码块,并捕捉错误,warning,警告信息,2,第,54,页,警告处理,警告用于提示用户在程序运行中出现异常情况。与错误不同的是,警告并不中断程序的运行,而是显示警告内容并继续执行。警告通过函数,warning,发出,格式与,error,函数相同,如:,warning(Input
34、must be a string),warning(formatted_warningmsg,arg1,arg2,.),warning(Ambiguous parameter name,%s.,param),另外,与错误相同,警告也可以使用消息标志符,用以显示该警告信息的类别及具体信息。警告处理的方式与错误处理的方式类似这里不再赘述。,2,第,55,页,程序设计的辅助函数,表达式与函数的评估,计时器函数,2,第,56,页,函数,功能,arrayfun,对数组的每个元素应用函数,builtin,以重载方式执行嵌套函数,cellfun,对单元数组的每个单元应用函数,echo,在执行中显示当前运行行
35、,eval,执行包含,MATLAB,表达式的字符串,evalc,评估,MATLAB,表达式,evalin,在指定工作区中运行表达式,feval,函数评估,iskeyword,判断输入字符串是否为,MATLAB,关键字,isvarname,判断输入字符串是否为,MATLAB,有效变量名,pause,暂停,等待用户反应,run,运行非当前路径下的脚本,script,脚本文件描述,structfun,对结构体的每个域运行函数,symvar,判断表达式中的符号变量,tic,toc,采用计数器评估函数的运行,2,第,57,页,计时器函数,函数,功能,delete,删除内存中的计时器对象,disp,显示计
36、时器对象的相关信息,get,获取计时器对象的属性,isvalid,判断计时器对象是否有效,set,设置或显示计时器对象的属性,start,开启计时器,startat,在指定时间启动计时器,stop,关闭计时器,timer,生成计时器对象,timerfind,查找计时器对象,timerfindall,查找计时器对象,包括不可见对象,wait,等待,直至计时器停止,2,第,58,页,调试程序,直接调试法,利用调试工具,采用命令行调试程序,采用调试界面调试程序,2,第,59,页,直接调试法,MATLAB,语言具有强大的运算能力,指令系统简单,因此程序通常非常简洁。对于简单的程序可以采用直接调试的方法
37、。,在程序调试时,程序运行中变量的值为一个重要的线索。因此,查看变量值为程序调试的重要线索,由于在函数调用时只返回最后的输出参数,而不返回中间变量,因此,可以选择下面的方法查看程序运行中的变量值。,(,1,)通过分析后,将可能出错的语句后面的分号(,;,)删除,将结果显示在命令窗口中,与预期值进行比较;,(,2,)利用函数,disp,显示中间变量的值;,(,3,)在程序中的适当位置添加,keyboard,指令。当,MATLAB,执行至此处时将暂停,等待用户反应。当程序运行至此时将暂停,在命令窗口中显示,k,提示符,用户可以查看工作区中的变量,可以改变变量的值。输入,return,指定返回程序,
38、继续运行。,(,4,)在调试一个单独的函数时,可以将函数改写为脚本文件,此时可以直接对输入参数赋值,然后以脚本方式运行该,M,文件,这样可以保存中间变量,在运行完成后,可以查看中间变量的值,对结果进行分析,查找错误所在。,2,第,60,页,采用命令行调试程序,函数,功能,dbstop,设置断点,dbclear,删除断点,dbcont,重新开始,dbdown,恢复由,dbup,修改的变量值,dbmex,启动,MEX,文件调试,dbstack,列出调用关系,dbstatus,列出所有的断点,dbstep,执行一行或多行,dbtype,列出,M,文件并标出每行,dbup,修改工作区中变量的值,dbq
39、uit,退出调试模式,2,第,61,页,函数,功能,echo,显示执行的脚本或函数代码,disp,显示指定变量的值或者其他信息,sprintf,,,fprintf,格式化输出不同类型的变量,whos,查看工作区中的变量,size,显示数组维数,keyboard,中断程序执行,将控制权交给键盘,允许键盘输入,return,在,keyboard,中断后继续返回程序执行,warning,显示指定的警告消息,error,显示指定的错误消息,lasterr,返回最后一条错误消息,lasterror,返回最后一条错误消息及相关信息,lastwarn,返回最后一条警告消息,2,第,62,页,文本编辑器中的,
40、Debug,菜单提供了全部的调试选项,另外,,MATLAB,主窗口中的,Debug,菜单提供了一些调试命令,方便调试时在命令窗口中查看运行状态。调试选项及其功能如表所示。,选项,功能,对应快捷键,Open M-files when Debbuging,选择该选项则在调试打开,M,文件,无,Step,下一步,F10,Step In,进入被调用函数内部,F11,Step Out,跳出当前函数,Shift+F11,Continue,执行,直至下一断点,F5,Go until Cursor,执行至当前光标处,无,Set/Clear Breakpoint,设置或删除断点,F12,Set/Modify C
41、onditional Breakpoint,设置或修改条件断点,无,Enable/Disable Breakpoint,开启或关闭光标行的断点,无,Clear Breakpoints in All Files,删除所有文件中的断点,无,Stop if Errors/Warings,遇到错误或者警告时停止,无,2,第,63,页,Set/Clear Breakpoint,,设置或清除断点。可以选择该选项对当前行进行操作,或者通过快捷键,F12,,或者直接点击该行左侧的“,-”,,如图所示。,设置断点时该处显示为红点。再次进行相同的操作则删除该断点。,2,第,64,页,Set/Modify Cond
42、itional Breakpoint,,该选项用于设置或修改条件断点。条件断点为一种特殊的断点,当满足指定的条件时则程序执行至此时停止,条件不满足时则程序继续进行。其设置界面如图,6-6,所示,在输入框中输入断点条件则将当前行设置为条件断点。,2,第,65,页,Enable/Disable Breakpoint,,该选项用于开启或关闭当前行的断点,如果当前行不存在断点,则设置当前行为断点;如果当前行是断点,则改变该断点的状态。在调试时,被关闭的断点将会被忽略。,在程序调试中,变量的值是查找错误的重要线索,在,MATLAB,中查看变量的值可以有三种方法:,(,1,)在编辑器中将鼠标放置在待查看的
43、变量处,停留,则在此处显示该变量的值;,(,2,)在工作区浏览器中查看该变量的值;,(,3,)在命令窗口中输入该变量的变量名,则显示该变量的值。,本节介绍了程序调试的函数和工具,在真正编写程序时,需要根据不同的情况灵活应用这些功能,达到最高的调试效率。,2,第,66,页,优化程序,通过,Profiler,进行程序运行分析,通过,tic,、,toc,函数进行程序运行分析,程序优化的常用方法,2,第,67,页,通过,Profiler,进行程序运行分析,Profiler,工具为,MATLAB,中的图形用户接口,用于分析程序运行时各个部分所消耗的时间,辅助用户进行程序优化。通过,Profiler,,用
44、户可以:,避免由于疏忽造成的非必要操作,替换运算较慢的算法,选择快速算法,通过存储变量的方式避免重复计算,通过,Profiler,工具进行程序运行分析通常按照下面的步骤进行:,(,1,)查看,Profiler,生成的总体报告,查找运行时间最多的函数或调用最频繁的函数。,(,2,)查看这些函数的详细报告,查找其中运行时间最多的语句或调用最频繁的语句。用户可以保存第一次分析的结果,以便修改后再次分析时进行比较。,(,3,)确定在运行时间最多的函数或代码行是否存在改进的可能。,(,4,)点击界面链接,打开相应文件,进行修改。,(,5,)重复进行上述的分析、修改,直到得到满意结果。,2,第,68,页,
45、1,打开,Profiler,MATLAB,中可以通过下列方式打开,Profiler,:,(,1,)点击,MATLAB,工具栏中的,Profiler,图标,激活,Profiler,工具;,(,2,)选择,Desktop-Profiler,;,(,3,)对于已经在编辑器中打开的,M,文件,选择,Tools-Open Profiler,;,(,4,)选中命令历史窗口中的一个或多个命令,点击右键,选择,Profile Code,;,(,5,)在命令窗口中输入:,profile viewer,。,2,第,69,页,2,运行,Profiler,Profiler,的界面如图所示。在,Run this cod
46、e,中输入需要分析的命令或表达式,点击,Start Profiling,,开始分析。需要注意的是,分析的表达式必须出于,MATLAB,的当前工作路径中,否则可能会得到错误的结果。,2,第,70,页,3,查看分析结果,分析完成后,,Profiler,会生成分析报告,包括总体报告和针对每个函数的详细报告。总体报告中包括函数名、被调用次数、总运行时间、函数单独运行时间(即不包括其子函数的运行时间)及函数运行时间的图形显示,如图所示。用户可以点击每列的标题改变结果的排序方式,也可以点击函数标题查看该函数的详细报告。,2,第,71,页,函数详细报告中包括该函数中每行代码的被调用次数和运行时间,并且可以显
47、示其中的子函数、函数列表等,如图所示。,2,第,72,页,4,通过,profile,函数进行程序运行分析,Profiler,的运行主要是基于,profile,函数的运行结果。这里对,profile,函数的使用做简单的介绍。,profile,函数的主要使用格式如表所示。,命令,说明,profile on,开始进行程序运行分析,清除已有的分析结果,profile on-detail level,指定分析的深度,,level,可以是,mmex,或者,builtin,,分别表示忽略或包括嵌套函数,profile on-history,指定记录函数调用的确切顺序,profile off,延缓分析,pro
48、file resume,继续进行分析,不清除已有的结果,profile viewer,打开,Profiler,s=profile(status),显示当前,profile,状态的结构体,stats=profile(info),延缓分析并显示当前,profile,状态的结构体,2,第,73,页,通过,tic,、,toc,函数进行程序运行分析,如果只需要了解程序的运行时间,或者比较一段程序在不同应用条件下的运行速度,可以通过计时器来进行。计时器包含两个函数:,tic,和,toc,。,tic,用于开始计时器,,toc,用于关闭计时器,并计算程序运行的总时间。如,tic,-,所需计时的程序代码,-,toc,对于小程序,如果其运行时间非常短,可以通过将其多次运行,计算总体时间的方法进行,如:,tic,for k=1:100,-,所需计时的程序代码,-,end,toc,2,第,74,页,程序优化的常用方法,使循环向量化,为数组预分配内存,以,MEX,文件的格式编写循环语句;,对向量赋值时尽量避免改变变量的类型或数组大小;,对实数进行操作,尽量避免复数的操作;,合理使用逻辑运算符;,避免重载,MATLAB,的内置函数和操作符;,通常情况下,函数的运行效率高于脚本文件;,Load,和,Save,函数效率高于文件输入输出函数;,避免在运行,MATLAB,时运行其他大型后台程序。,