1、第四章 MATLAB编程基础,4.1 概述 4.2 流程控制 4.3 脚本文件 4.4 函数文件 4.5 M文件调试 4.6 M文件性能分析 4.7 本章小结,4.1 概 述,MATLAB提供了完整的编写应用程序的能力,这种能力通过一种被称为M语言的高级语言来实现。这种编程语言是一种解释性语言,利用该语言编写的代码仅能被MATLAB接受,被MATLAB解释、执行。其实,一个M语言文件就是由若干MATLAB的命令组合在一起构成的,这些命令都是在前面章节中介绍的合法的MATLAB命令。和C语言类似,M语言文件都是标准的纯文本格式的文件,其文件的扩展名为.m。,使用M文件最直接的好处就是可以将一组M
2、ATLAB命令组合起来,通过一个简单的指令就可以执行这些命令。这些命令可以完成某些MATLAB的操作,也可以实现某个具体的算法。其实,MATLAB产品族中包含的工具箱就是由世界上在相应专业领域内的顶尖高手,利用M语言开发的算法函数文件集合。读者也可以结合自己工作的需要,为自己的MATLAB开发具体的算法和工具箱。 MATLAB的函数主要有两类,一类被称为内建(Build-in)函数,这类函数是由MATLAB的内核提供的,能够完成基本的运算,例如三角函数、矩阵运算的函数等。另外一类函数就是利用高级语言开发的函数文件,这里的函数文件既包括用C语言开发的MEX函数文件,又包含了M函数文件。有关MEX
3、函数文件的内容已经超出了本书的内容,将在MATLAB外部编程接口一书中详细讲述。,如前所述,MATLAB的M语言文件是纯文本格式的文件,利用任何一种纯文本编辑器都可以编写相应的文件,例如Windows平台下的记事本、UltraEdit等软件,或者Unix平台下的Emacs软件等。同样,为了方便编辑M文件,MATLAB也提供了一个编辑器,叫作meditor,它也是系统默认的M文件编辑器。 运行meditor的方法非常简单,在MATLAB命令行窗口中键入下面的指令就可以打开meditor: edit 这时MATLAB将启动meditor,然后创建一个未命名的空白文件,如图4-1所示。,图4-1 m
4、editor的运行界面,这时用户就可以直接在编辑器中键入MATLAB指令,开发M语言文件了。 此外,运行meditor还可以通过“File”菜单中“New”子菜单下的“M-File”命令来实现,或者直接单击MATLAB用户界面工具栏上的新建按钮完成同样的工作。 M语言文件可以分为两类,其中一类是脚本文件,另外一类叫作函数文件。本章将分别介绍这两类文件的编写方法。,4.2 流 程 控 制,4.2.1 选择结构 如前所述,当人们判断某一条件是否满足,根据判断的结果来选择不同的解决问题的方法时,就需要使用选择结构。和C语言类似,MATLAB的条件判断可以使用if语句或者switch 语句。,4.2.
5、1.1 if语句if语句的基本语法结构有三种,分别如下:(1) if (关系运算表达式)MATLAB语句end 这种形式的选择结构表示,当关系运算表达式计算的结果为逻辑真的时候,执行MATLAB语句,这里的MATLAB语句可以是一个MATLAB表达式,也可以是多个MATLAB表达式。在MATLAB语句的结尾处,必须有关键字end。,(2) if(关系运算表达式)MATLAB语句A elseMATLAB语句B end 这种选择结构表示,当关系运算表达式的计算结果为逻辑真的时候,执行MATLAB语句A,否则执行MATLAB语句B,在语句B的结尾必须具有关键字end。,例子4-1 if语句的使用if
6、_examp.m。 读者通过本例子将同时了解meditor的基本使用方法。打开meditor,然后键入下面的指令:001clear all002003I=1;004J=2;005006if I = J007A(I,J) = 2;008elseif abs(I-J) = 1009A(I,J) = ?1;010else011A(I,J) = 0;012end,注意: 在键入程序时,不要将行号(001012)也敲进去,在这里设置行号的主要目的是为了便于讲解和分析程序。 所有的指令键入完毕后,将文件保存,读者可以将其保存为任何名字,不过文件名必须由英文字符和数字组成,将文件的扩展名设置为.m,并且将文
7、件保存在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的语句结构也可以嵌套地使用,也就是可以存在这样的语句结构:,if(关系表达式a)if(关系表达式
8、b) MATLAB语句Aelse MATLAB语句Bendelseif(关系表达式c) MATLAB语句Celse MATLAB语句Dendend,注意:在使用嵌套的选择结构时,需要小心if语句和end关键字的配对。例子4-2 嵌套使用的if结构if_examp2.m。001clear all002003if 1004 disp(Is 1)005else006 disp(Not 1)007end008,009I = 1;010if I011 if I -2016 dis(I is less than 0 but bigger than -2)017 end018end,该程序的运行方法和效果如
9、下: if_examp2Is 1I is bigger than 0 but less than 2 在例子4-2中,主要说明了嵌套的if结构和在关系表达式中使用常量的方法。在代码的003行,if语句的关系表达式为常数1,这个时候if语句将始终认为非零值为逻辑真,所以,程序执行了004行的代码。同样,在程序的009行,if语句的关系表达式为变量I,若I的数值为非零值,则if语句判断其为逻辑真,所以,代码的016行只有在I为0时,才可能被执行。,4.2.1.2 switch语句 另外一种构成选择结构的关键字就是switch。在处理实际问题的时候,往往要处理多个分支,这时如果使用if-else语句
10、处理多分支结构往往使程序变得十分冗长,从而降低了程序的可读性。switch语句就可以用于处理这种多分支的选择,它的基本语法结构如下:,在switch语句之后的表达式可以是一个数值类型表达式或者是一个数值类型的变量,当这个表达式的值同case后面的某一个常量表达式相等时,则执行该case后面的常量表达式后面的语句。 注意: MATLAB的switch和C语言的switch语句结构不同。在C语言中,每一个case后面的语句中必须包含类似break语句的流程控制语句,否则程序会依次执行符合条件的case语句后面的每一个case分支。但是在MATLAB中就不必如此,程序仅仅执行符合条件的case分支。
11、,例子4-3 switch结构使用示例switch_examp.m。001clear all002003algorithm = input(Enter an algorithm in quotes (ode23, ode15s, etc:) );004005switch algorithm006case ode23007str = 2nd/3rd order;008case ode15s, ode23s009 str = stiff system; 010otherwise011str = other algorithm;012end013disp(str);,该文件的运行方法和效果如下: s
12、witch_exampEnter an algorithm in quotes (ode23, ode15s, etc:) ode232nd/3rd order switch_exampEnter an algorithm in quotes (ode23, ode15s, etc:) ode4other algorithm,例子4-3中需要用户在执行程序的过程中输入一个字符串,switch语句根据用户的输入判断执行相应的case分支。若没有符合条件的case分支,则switch执行otherwise后面的语句。若switch结构中没有定义otherwise及其相应的代码,则程序不会进行任何操
13、作,而是直接退出switch结构。 提示: 在处理以字符串变量或者常量参与的关系判断操作时,使用switch结构要比if-else结构效率高一些。 由于MATLAB的switch结构没有C语言的fall-through特性,所以,如果需要针对多个条件而使用同一个case分支的时候,需要使用元胞数组与之配合,参见例子4-4。,例子4-4 switch结构使用示例switch_examp2.m。001clear all002003var = input(Input a Numer:);004switch var005 case 1006 disp(1)007 case 2,3,4008 disp(
14、2 or 3 or 4)009 case 5010 disp(5)011 otherwise012 disp(something else)013end,例子4-4运行的方法和效果如下: switch_examp2Input a Numer:11 switch_examp2Input a Numer:32 or 3 or 4 switch_examp2Input a Numer:7something else,例子4-4代码的核心部分为007行,这里使用元胞数组增加判断条件的个数,当输入的数字为2、3或者4时,switch结构将使用同一个case分支进行判断、计算。 注意: 从代码的完整性和可
15、靠性角度出发,在使用switch语句时,一定要包含otherwise分支,这是一种良好的编程习惯。,4.2.2 循环结构 在解决很多问题的时候需要使用循环结构,例如求解数列的和或者进行某种迭代法求解数值方程时,都需要循环结构配合完成计算。 在MATLAB中,包含两种循环结构,一种是循环次数不确定的while循环,而另一种是循环次数确定的for循环。,1while循环结构while语句可以用来实现“当”型的循环结构,它的一般形式如下:while(表达式)MATLAB语句end 当表达式为真时,循环将执行由语句构成的循环体,其特点是先判断循环条件,如果循环条件成立,即表达式运算结果为“真”,再执行
16、循环体。循环体执行的语句可以是一句也可以是多句,在MATLAB语句之后必须使用关键字end作为整个循环结构的结束。另外,在循环过程中一定要能够改变关系表达式或者布尔类型变量的值,或者使用其他方法来跳出循环,否则会陷入死循环(无法正常退出的循环叫作死循环)。,例子4-5 使用while语句求解。001i = 1;002sum = 0;003while ( i while_example 计算结果为:500500 例子4-5的002006行使用了while循环结构,在循环结构中进行了累加的操作。需要注意的是,在MATLAB中没有类似C语言的+或者+=等运算操作符,因此在进行诸如累加或者递减的运算时
17、,不得不给出完整的表达式。另外,例子4-5求数列和的算法的运算效率很低,在MATLAB中不要使用这样的结构完成类似的运算,而需要采用向量化的计算。,注意: while循环结构的关系表达式可以是某个数据变量或者常量,这时,将按照非零值为逻辑真进行相应的操作。另外,在进行上述操作时,若数据变量为空矩阵,则while语句将空矩阵作为逻辑假处理,也就是说,在while A MATLAB语句S1 end结构中,若A为空矩阵,则MATLAB语句S1永远不会被执行。,2for循环结构 使用for语句构成循环是最灵活、简便的方法,不过,使用for语句循环需要预先知道循环体执行的次数,所以这种循环一般叫作确定循
18、环。在MATLAB中for循环的基本结构如下:for index = start:increment:endMATLAB语句end其中,index的取值取决于start和end的值,一般地,这里通常使用等差的数列向量,参见例子4-6。,例子4-6 使用for语句求解 。001sum = 0;002for i = 1:1000003 sum = sum+i;004end005str = 计算结果为:,num2str(sum);006disp(str),例子4-6运行的结果为 for_example计算结果为:500500 在例子4-6中,002行的代码使用了确定次数的for循环结构,循环次数使用
19、行向量进行控制,而且索引值i按照默认的数值1进行递增。 在for循环语句中,不仅可以使用行向量进行循环迭代的处理,也可以使用矩阵作为循环次数的控制变量,这时循环的索引值将直接使用矩阵的每一列,循环的次数为矩阵的列数,参见例子4-7。,例子4-7 for循环示例。001A = rand(3,4);002003for i = A004 sum = mean(i)005end例子4-7运行的结果为 for_matricessum = 0.2728sum = 0.6649sum = 0.4275sum = 0.5220,例子4-7尽管只有短短的几行,但是在003行使用了一个矩阵作为循环的索引值,于是,
20、循环结果就分别计算矩阵的每一列元素的均值。 和其他高级语言类似,MATLAB的循环结构也可以进行嵌套使用,使用嵌套的循环需要注意for关键字和end关键字之间的配对使用,请读者根据高级语言的一般特性来推断其运行的方式,这里就不再赘述了。,4.2.3 break语句和continue语句 在循环结构中还有两条语句会影响程序的流程,这就是break语句和continue语句,这两条语句的基本功能如下: 当break语句使用在循环体中的时候,其作用是能够在执行循环体的时候强迫终止循环,即控制程序的流程,使其提前退出循环,它的使用方法是break; continue语句出现在循环体中的时候,其作用是能
21、够中断本次的循环体运行,将程序的流程跳转到判断循环条件的语句处,继续下一次的循环,它的使用方法是continue;,例子4-8 break语句示例break_example.m。001i = 0;002j = 0;003k = 0;004for i = 1:2005 for j = 1:2006 for k = 1:2007 if(k = 2)008 disp(退出循环);009 break;010 end,011 str = sprintf(I = %d , J = %d , K = %d,i,j,k);012 disp(str);013 end014 end015end016disp(程序
22、运行结束);,例子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退出循环程序运行结束,break语句的作用是退出当前的循环结构运行,所以在例子4-8中,位于最内层循环的break语句执行的结果是退出了最内层的循环k,位于外层的循环i和j还是都运行完毕了。,例子4-9 continue语句示例。001i = 0;002for i =1:6003 if(i3)004 continue005 else00
23、6 str = sprintf(I = %d,i);007 disp(str);008 end009end010str = sprintf(循环结束 I = %d,i);011disp(str);,例子4-9的运行结果如下: continue_exampleI = 1I = 2I = 3循环结束 I = 6 continue语句的作用在例子4-9中得到了充分说明,该语句终止当前的循环,然后继续下一次循环运算,直到所有的循环迭代运算结束为止。,4.2.4 提高运算性能 M语言和其他的高级语言不同,由于采用了解释型语言,所以M语言的执行效率肯定低于编译型语言(例如C语言)。然而,随着MATLAB版
24、本的不断升级,再加之合理利用MATLAB向量运算等特点可以较大幅度地提高M语言代码的执行效率。在本小节结合一些具体的例子来讲述M语言编程以及MATLAB软件本身在提高程序执行效率方面的一些特性。,1向量化运算 首先,希望读者牢记这样一点,MATLAB最初的目的是提供便利的矩阵数据操作能力。所以在大多数的应用程序中,不要使用循环结构操作矩阵的元素,应直接使用矩阵元素的索引或者矩阵运算的函数,这样做不仅能够提高代码的执行效率,而且还能够提高程序的可读性,这就是所谓的向量化的运算,也就是说,尽量将使用while循环或者for循环的语句结构转换成等价的向量或者矩阵运算,以提高程序的运算速度,参见例子4
25、-10。,例子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,012013disp(char(10), 使用循环结构:)014tic;015for I = 1:r
26、ows016 for J = 1:cols017 Density(I) = Mass(I,J)/(Length(I,J)*Width(I,J)*Height(I,J);018 end019end020toc,例子4-10比较了循环结构和数组运算的执行效率,程序中分别在010行使用数组运算和在015019行使用循环结构完成了同样的工作。程序的运行结果如下: array_vs_loops使用数组运算:elapsed_time = 0使用循环结构:elapsed_time = 0.0100,2预分配存储空间 另外一种能够提高运算效率的方法就是进行内存变量存储空间的预分配,首先察看例子4-11。 例子
27、4-11 内存预分配的例子 pre_allocate.m。001disp(char(10), 使用内存预分配:)002pre_allo = zeros(10000,1); 003tic;004for I = 1:10000005 pre_allo(I) = rand(1); 006end,007toc008009disp(char(10), 不使用内存预分配:)010tic;011for J = 1:10000012 not_pre_allo(J) = rand(1); 013end014toc,例子4-11的执行结果如下: pre_allocate使用内存预分配:elapsed_time =
28、 0.0900不使用内存预分配:elapsed_time = 0.3410,上面两种不同的运算惟一的区别就是程序002行,执行这行语句之后,MATLAB自动分配了10 000个连续的内存空间用于存储数据,MATLAB将一次创建足够的存储空间,然后依次赋值。而后者not_pre_alloc变量没有进行相应的操作,所以带来了两次运算结果的不同。 在不使用内存预分配的运算中,MATLAB是如何进行操作的呢? 当I=1时,MATLAB将使用一小块长度为一个单元大小的内存保存一位随机数。 当I=2时,MATLAB寻找一块两单元大小的内存区,一个单元放第一个随机数,第二个放另外一个随机数。,当I = 10
29、000 时,MATLAB 寻找一块容纳10000单元的内存区存放以前的9999个随机数,同时把最新的一个随机数加入进去。代码运行的结果造成了存储空间的浪费,降低了程序的执行速度。 所以,在编写M语言程序的时候需要尽量使用内存的预分配,而少使用或者不使用数组内存空间的自动扩充方式。MATLAB针对不同的数据类型有不同的内存预分配函数,见表4-1。,表4-1 内存预分配函数,表4-1中说明了不同数据类型所要使用的内存预分配函数,其中结构类型的数组需要两个函数配合使用,利用struct函数构造结构,而使用repmat函数创建数组。 对于非双精度类型的数据,例如整数类型或者单精度类型,进行内存的预分配
30、时,需要使用相应的构造函数或者类型转换函数,例如:Y = int16(zeros(1:10000); 在上面的表达式中创建了连续的10 000个16位整数的存储空间。 当预先分配的内存空间无法容纳数据时,则可以通过repmat函数来扩充数组的存储空间。,3MATLAB加速器 尽管利用了上述的特性可以明显提高M语言的运行效率,但是在同等条件下,M语言的效率还是无法和第四代高级编程语言的执行效率相媲美,于是,在MATLAB 6.5版本中,新增加了MATLAB性能加速器这样一个新特性。MATLAB性能加速器能够明显改善循环结构、内建函数调用等方面的运行效率,特别是在处理循环迭代次数确定的for循环结
31、构中,其运算速度较早期的MATLAB版本有很大的提高,在表4-2中总结了MATLAB加速器能够发挥作用的M语言元素。,表4-2 加速器能够影响的M语言元素,表4-3 性能加速器不起作用的M语言元素,例子4-12 性能加速器说明jitaccel.m。001tic002A = rand(500000,1);003B = zeros(500000,1);004B(1) = A(1);005for i = 2:500000006 B(i) = B(i?1) + A(i);007end008toc,在MATLAB 6.1中: jitaccelelapsed_time = 5.2780在MATLAB 6.
32、5中: jitaccelelapsed_time = 0.0900若直接使用内建函数,则运行的效果为 tic;B = cumsum(A,1);tocelapsed_time = 0.0200,通过比较,可以看出MATLAB性能加速器明显提高了程序的执行效率,在有些情况下,加速器使执行速度提高10100倍。 注意: 例子4-12代码运算得到的时间和具体运行MATLAB的计算机的性能有关,不同的计算机环境得到的计算结果不尽相同。另外,MATLAB性能加速器在MATLAB 6.5中的默认设置为开启(On)状态。,4.3 脚 本 文 件,脚本文件是最简单的一种M语言文件,在本章前面章节的例子中都使用了
33、脚本文件。所谓脚本文件,就是由一系列的MATLAB指令和命令组成的纯文本格式的M文件,执行脚本文件时,文件中的指令或者命令按照出现在脚本文件中的顺序依次执行。脚本文件没有输入参数,也没有输出参数,执行起来就像早期的DOS操作系统的批处理文件一样,而脚本文件处理的数据或者变量必须在MATLAB的公共工作空间中。,例子4-13 脚本文件示例。001% 注释行002% M脚本文件示例 003% flower petal 004% 以下为代码行005% 计算006theta = -pi:0.01:pi; 007rho(1,:) = 2*sin(5*theta).2;008rho(2,:) = cos(
34、10*theta).3;009rho(3,:) = sin(theta).2;010rho(4,:) = 5*cos(3.5*theta).3;,011 for k = 1:4012 % 图形输出013 subplot(2,2,k)014 polar(theta,rho(k,:) 015end016disp(程序运行结束!)在MATLAB命令行中运行该脚本文件: script_example程序运行结束!,图4-2 例子4-13脚本文件的运行结果,仔细察看例子4-13的脚本文件,在脚本文件中,主要由注释行和代码行组成。M文件的注释行需要使用%定义符,在%之后的所有文本都认为是注释文本,不过,M
35、文件的注释定义符仅能影响一行代码,类似于C+语言中的“/”。然而在M语言中,没有类似C语言的注释定义符“/*”和“*/”,所以无法一次定义多行注释。给程序添加适当的注释是良好的编程习惯,希望读者能够在日常编程中多多使用。,脚本文件中的代码行都是一些简单的MATLAB指令或者命令,这些命令可以用来完成相应的计算处理数据、绘制图形结果的操作,也可以在脚本文件中调用其他的函数完成复杂的数学运算,在例子4-13中就完成了这些工作。另外,在MATLAB中还有一些指令用来处理程序和用户之间的交互,在表4-4中进行了总结。,表4-4 脚本文件中常用的MATLAB指令,MATLAB一般使用脚本文件作为某种批处
36、理文件,其中,有两个批处理文件经常被MATLAB自动调用,这两个脚本文件分别为startup.m和finish.m。 startup.m文件在MATLAB启动时自动被执行,用户可以自己创建并定义编写该文件,例如在文件中添加物理常量的定义、系统变量的设置或者MATLAB搜索路径的设置。当用户安装MATLAB之后,在toolboxlocal路径下有一个M文件,名为Starupsav.m,该文件可以看作是startup.m文件的模板,可以修改该文件,然后将其以文件名startup.m的形式保存在toolboxlocal路径下。,与startup.m文件相对应的是finish.m文件,该文件在MATL
37、AB退出时自动执行,用户可以自己创建并定义编写该文件,例如在文件中添加保存数据等指令,这样可以将每次退出前的工作结果进行保留。同样,在toolboxlocal路径下有两个文件,分别为finishsav.m和finishdlg.m,这两个文件可以用来作为finish.m文件的模板,相关的具体内容介绍请读者自己察看相应的文件和帮助文档。,4.4 函 数 文 件,4.4.1 基本结构 M函数文件和脚本文件不同,函数文件不仅有自己特殊的文件格式,不同的函数还分别具有自己的工作空间。同其他高级语言类似,M函数文件也有局部变量和全局变量。读者首先需要了解的是函数文件的基本结构,参见例子4-14。,例子4-
38、14 函数文件示例average.m。001function y = average(x)002% AVERAGE 求向量元素的均值003% 语法:004% Y = average(X)005% 其中,X 是向量,Y为计算得到向量元素的均值006% 若输入参数为非向量则出错007008% 代码行009m,n = size(x);010% 判断输入参数是否为向量,011if (m = 1) | (n = 1) | (m = 1 ,在MATLAB命令行中,键入下面的指令运行例子4-14的代码: z = 1:99; y = average(z)y = 50,M语言函数文件具有下面的不同部分:* 函数
39、定义行。* 在线帮助。* 注释行。* M语言代码。,下面结合例子4-14分别说明这些部分的构成。函数定义行,例子4-14的函数定义行为代码的001行:001function y = average(x),这一行代码中包括关键字function、函数输出参数y、函数的名称average和函数的输入参数x。需要读者注意的是函数的名称,函数的名称定义要求必须以字符开头,后面可以用字符、数字和下划线的组合构成函数名称。MATLAB对函数名称的长度有限定,读者可以在自己的MATLAB中,通过执行namelengthmax函数获取相应的数值。假设该函数返回的数值为N,若函数的名称长度超过了N,则MATLA
40、B使用函数名称的前N个字符作为函数名称。 一般推荐将函数名称用小写的英文字符表示,同时函数的M文件名称最好和函数名称保持一致,若文件名称和函数名称不一致,则调用函数的时候需要使用文件名称而非函数名称。,M函数文件的在线帮助为紧随在函数定义行的注释行。在例子4-14中,average函数的在线帮助为002006行的注释行。若在MATLAB命令行中键入下面的指令: help average在MATLAB的命令窗口中就会出现:AVERAGE 求向量元素的均值语法:Y = average(X)其中,X是向量,Y为计算得到向量元素的均值若输入参数为非向量则出错,由于H1帮助行的特殊作用,所以在用户自己定
41、义M函数文件时,一定要编写相应的H1帮助行,对函数进行简明、扼要的说明或者解释。 例子4-14的008、010、012、015行代码分别是程序具体的注释行,这些注释行不会显示在在线帮助中,主要原因就是这些注释行没有紧随在H1帮助行的后面,其中008行的注释与在线帮助之间有一个空行。其实从008行开始一直到文件的结尾都是M函数文件的代码行,这些代码行需要完成具体的算法,实现用户的具体功能。代码行就是用户开发的算法M语言的实现。,4.4.2 输入输出参数 M语言函数文件的输入、输出参数和其他高级语言的输入、输出参数不同,在定义这些输入、输出参数的时候不需要指出变量的类型,因为MATLAB默认这些参
42、数都使用双精度类型,这样可以简化程序的编写。而且在定义参数时,也没有确定输入参数的维数或者尺寸,也就是说,直接从参数上无法判断输入来的是标量、向量还是矩阵,只有通过程序内部的具体代码来加以判断。 M语言的函数文件不仅可以有一个输入参数和一个返回值,还可以为M语言函数文件定义多个输入参数和多个输出参数,见例子4-15。,例子4-15 多个输入、输出参数的M函数。001function avg, stdev, r = ourstats(x,tol)002% OURSTATS 多输入输出参数示例003% 该函数计算处理矩阵,得到相应的均值、004% 标准差和矩阵的秩005m,n = size(x);
43、006if m = 1007 m = n;008end009% Average010avg = sum(x)/m;,011% Sandad deviation012stdev = sqrt(sum(x.2)/m - avg.2);013% Rank014s = svd(x);015r = sum(s tol);运行例子4-15,在MATLAB命令行中,键入下面的指令: A = 1 2 3; 4 5 6A = 1 2 3 4 5 6, a,s,r = ourstats(A,0.1)a = 2.5000 3.5000 4.5000s = 1.5000 1.5000 1.5000r = 2 ours
44、tats(A,0.1)ans = 2.5000 3.5000 4.5000 a,s = ourstats(A,0.1)a = 2.5000 3.5000 4.5000s = 1.5000 1.5000 1.5000,例子4-15的M代码具有两个输入参数、三个输出参数,所以在使用该函数的时候,需要将必要的输入、输出参数写明。注意调用该函数时的语法,将输出参数依次写在一个向量中,若输出参数的个数与函数定义的输出参数个数不一致,则在例子4-15中,将计算得到的前几个输出参数作为返回值,个数等于用户指定的输出参数个数。计算的结果依次赋值给不同的变量。 在使用多个输入、输出参数的时候,往往需要判断用户写明的输入、输出参数的个数,若个数与函数定义不符合的时候,将给出错误或者警告信息,这个时候,需要使用函数nargin和nargout来获取函数的输入、输出参数个数,见例子4-16。,