![MATLAB/Simulink权威指南:开发环境、程序设计、系统仿真与案例实战](https://wfqqreader-1252317822.image.myqcloud.com/cover/629/27111629/b_27111629.jpg)
3.3 M函数文件
M函数文件是一种重要的M文件,每个函数文件都定义为一个函数。MATLAB提供的各种函数基本都是由函数文件定义的。
3.3.1 M函数文件的格式
M函数文件由function声明行开头,其格式如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P134_28985.jpg?sign=1738883881-rgowr5STMbMIkMjiYKJoNgYCWNM23jVv-0-c9c2134f15f3283b0853d1a878180643)
其中,以function开头的这行为函数声明行,表示该M文件是一个函数文件。Untitled4为函数名,函数名的命名规则和变量名相同。input_args为函数的输入形参列表,多个参数间用“,”分隔,用圆括号括起来。output_args为函数的输出形参列表,多个参数间用“,”分隔,当输出参数为两个或两个以上时,用方括号括起来。
M函数文件说明如下:
(1)M函数文件中的函数声明行是必不可少的,必须以function语句开头,用以区分M脚本文件和M函数文件。
(2)M函数文件名和声明行中的函数名最好相同,以免出错。如果不同,MATLAB将忽略函数名而确认函数文件名,调用时使用函数文件名。
(3)注释说明要以%开头,第一注释行一般包括大写的函数文件名和函数功能信息,可以提供lookfor和help命令查询使用。第二及以后注释行为帮助文本,提供M函数文件更加详细的说明信息,通常包括函数的功能,输入和输出参数的含义,调用格式说明,以及版权信息,便于M文件查询和管理。
例如,在命令窗口使用lookfor和help命令查找已经编写好的函数文件“fexam_3_13”的注释说明信息。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P135_28986.jpg?sign=1738883881-hHPh41LHN0bi0lJPcB1vvwGrJT7Q0X6a-0-f83f519d3dfb1585232d9cd3ad801a67)
由以上结果可知,lookfor命令只显示注释的第一行信息,而help命令显示所有注释信息。
如果用lookfor命令查询perimeter关键字,可以查询到已经编写过的有关周长perimeter的函数文件,如下所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P135_28987.jpg?sign=1738883881-WfqMJ1vl1thtV9rvF32g133tJQy4BxJs-0-286c05e942d2d66acc1be2cfedee3583)
3.3.2 M函数文件的调用
M函数文件编写好后,就可以在命令窗口或者M脚本文件中调用函数。函数调用的一般格式如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P135_28988.jpg?sign=1738883881-lkPIX2AIvDgcvafnhSTptfPOGKCvkRJA-0-e1f31e3697cf679767022e2d720682e6)
需要注意,函数调用时各实参数列表出现的顺序和个数,应与函数定义时的形参列表的顺序和个数一致,否则会出错。函数调用时,先将输入实参数传送给相应的形参数,然后再执行函数,函数将输出形参数传送给输出实参数,从而实现参数的传递。
【例3-15】 编写函数文件,实现极坐标(ρ,θ)与直角坐标(x,y)之间的转换。
已知转换公式为
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28991.jpg?sign=1738883881-fZPRdcR2OWo1BSxl2gu6OiAVo4jVRzSt-0-3c9fc6c6b2e4998e168bc4091b3cfeb2)
函数文件ftran.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28992.jpg?sign=1738883881-wO4PWF9IYe0oJQnKgm6yqIY6ojSgjAGy-0-9b47363152cd66e946035fca1159cf2d)
在命令窗口可以直接调用函数文件ftran.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28993.jpg?sign=1738883881-D5vouUx1lKCV9MFHO0DmDzFwTGGpDouI-0-cb87cebb2e6e7a2209d1f2d339809a20)
也可以编写调用函数文件ftran.m的M脚本文件exam_3_15.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28994.jpg?sign=1738883881-BMT7hrcO7UZEV0NeO9rFEC5sBaa8rRId-0-ab440a297698a5d23b9d034eb3089d63)
运行M脚本文件exam_3_15.m,结果如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28995.jpg?sign=1738883881-hPAS34BnFJpDx0KaSxZc9jzjoC8YlxPr-0-d54cc490f9fd1e0e0242dab87a9535e9)
3.3.3 主函数和子函数
1.主函数
在MATLAB中,一个M文件可以包含一个或者多个函数,但只能有一个主函数,主函数一般出现在文件最上方,主函数名与M函数文件名相同。
2.子函数
在一个M函数文件中若有多个函数,则除了第一个主函数以外,其余函数都是子函数。子函数的说明如下:
(1)子函数只能被同一文件中的函数调用,不能被其他文件调用;
(2)各子函数的次序没有限制;
(3)同一文件的主函数和子函数的工作空间是不同的。
【例3-16】 分段函数如下所示,编写M函数文件,使用主函数exam_3_16.m调用三个子函数y1、y2和y3的方式,实现分段函数相应曲线绘制的任务,其中,a、b和c分别从屏幕输入1、2和3。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P137_28996.jpg?sign=1738883881-XMTZGOY2LCgFuNVQBsZfwMQeeTvaVNq2-0-e10d0d0d491c186bbc60b69d3967f11a)
M函数文件exam_3_16.m如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P137_28997.jpg?sign=1738883881-LyEGmZC9UAzue0PSTh9fGofbsiQvBJAC-0-48f9d7b0efd7705e84cde487698e85fc)
在命令窗口直接调用函数文件exam_3_16.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P138_28999.jpg?sign=1738883881-h0gzBq0AjldUZdbCHPNEE5cCeH0kYVVI-0-32af922dbb21f33a9bbe132b5245a856)
结果如图3-9所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P138_9528.jpg?sign=1738883881-ADTxwIo7ohg7nSwGpA4EoavsK7m8Mzve-0-6f5daf896da06b520a4cbd01ead3eae1)
图3-9 ax2+bx+c曲线(z=1)
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P138_29000.jpg?sign=1738883881-s4mo4nc9l589KkFVgqniQU3v6oKvGp4h-0-73b343a2c1cd8c5668b93be55653b842)
结果如图3-10所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P138_29001.jpg?sign=1738883881-AkgoJy50YUkZNGlj6xUIIAvMn9jScCc7-0-ff55b768153411f65eadb8b5c89a4a55)
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P139_9548.jpg?sign=1738883881-zq2rHa7tP9plh4iyOzCjItN5lPFj4rqJ-0-4667afbcad92adf878f0c0a21b80241b)
图3-10 asin(x)+b曲线(z=2)
结果如图3-11所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P139_9552.jpg?sign=1738883881-Gk4zPjTwd9IZsVwArGOnDrU3G4lmIzZi-0-e23f5ddd57ddbee416f3d0d6183d9526)
图3-11 ln|a+b/x|曲线(z=3)
该M函数文件由一个主函数exam_3_16和三个子函数y1、y2和y3组成,它们的变量空间是相互独立的。可以用help命令查找子函数的帮助信息,格式是“help文件名>子函数名”。例如,查找“exam_3_16”文件中的子函数y1的帮助信息:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P139_29003.jpg?sign=1738883881-4c7ZQmw3LR4guKjOUHSP2XVu8CTwBTJj-0-f9b878f0726827086466e60898129c47)
3.3.4 函数的参数
MATLAB语言的函数参数包括函数的输入参数和输出参数。函数通过输入参数接收数据,经过函数执行后由输出参数输出结果,因此,MATLAB的函数调用就是输入输出参数传递的过程。
1.参数的传递
函数的参数传递是将主函数中的变量值传送给被调函数的输入参数,被调函数执行后,将结果通过被调函数的输出参数传送给主函数的变量。被调函数的输入和输出参数都存放在函数的工作空间中,与MATLAB的工作空间是独立的,当调用结束后,函数的工作空间数据被清除,被调函数的输入和输出参数也被清除。
例如,在MATLAB命令空间调用例3-15已创建的函数ftran.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P140_29004.jpg?sign=1738883881-WOF07VTBd3cBua02poMd8Td2wylCr8FG-0-6ca9430471f522d5ae5a1bcd8c31aab1)
可知,将变量r和x的值传送给函数的输入变量rho和thetha,函数运行后,将函数的输出变量x和y传送给工作空间中的xx和yy变量。
2.参数的个数
MATLAB函数的输入输出参数使用时,不用事先声明和定义,参数的个数可以改变。MATLAB语言提供nargin和nargout函数获得实际调用时函数的输入和输出参数的个数。还可以用varagrin和varargout函数获得输入和输出参数的内容。
(1)nargin和nargout函数可以分别获得函数的输入和输出参数的个数,调用格式如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P140_29005.jpg?sign=1738883881-YsicncyRbudRzr35ZcVn1dOPbH7wg1H5-0-302ec39c196a0945211e2aed03b591c2)
其中,fun是函数名,x是函数的输入参数个数,y是函数的输出参数个数。当nargin和nargout在函数体内时,fun可以省略。
例如,用nargin和nargout函数求例3-15创建的函数ftran.m的输入和输出参数的个数。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P140_29007.jpg?sign=1738883881-u8sNP9T5E6OKhrVyov220e6vwkgEAkhJ-0-49cf572de6daa587b4d9359050502ed8)
(2)MATLAB提供了varargin和varargout函数,将函数调用时实际传递的参数构成元胞数组,通过访问元胞数组中各元素的内容来获得输入和输出变量。varargin和varargout函数的格式如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P141_29009.jpg?sign=1738883881-RohU6qShEW33Cdjr5XYtTV6oSXB3SAO9-0-99b7c4f11f2de90b8d47b5722eeed2bf)
【例3-17】 根据输入参数的个数使用varargin和varargout函数,绘制sin(x)不同线型的曲线。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P141_29010.jpg?sign=1738883881-OhvyFeC8Tc2xmduyKlyfdiuNznkkpL9V-0-a5ae10a1de06eda59abf1f2bf4fdd547)
在MATLAB命令空间输入下列命令,执行该函数,显示的曲线如图3-12所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P141_29011.jpg?sign=1738883881-UOYYsmiTPEHz1HgHcXzYDh4kEYyK6nWy-0-374146f1a376b097abf4b4bfdbd198c9)
需要注意,varargin和varargout函数获得的都是元胞数组。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P142_9626.jpg?sign=1738883881-Wl2Fbinqbjm2YT7OLuzcCiSdu8ZKK76H-0-b8d5dd7d466cd6d5bcbf3fa1a4b0cc5b)
图3-12 画出三条曲线
3.3.5 函数的变量
MATLAB的函数变量根据作用范围,可以分为局部变量和全局变量。
1.局部变量
局部变量(Local Variables)的作用范围是函数的内部,函数内部的变量如果没有特别声明,都是局部变量。都有自己的函数工作空间,与MATLAB工作空间是独立的,局部变量仅在函数内部执行时存在,当函数执行完,变量就消失。
2.全局变量
全局变量(Global Variables)的作用范围是全局的,可以在不同的函数和MATLAB工作空间中共享。使用全局变量可以减少参数的传递,有效地提高程序的执行效率。
全局变量在使用前必须用“global”命令声明,而且每个要共享的全局变量的函数和工作空间,都必须逐个使用“global”对该变量声明。格式如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P142_29012.jpg?sign=1738883881-HOsFEHGgt8Izng6XVCUY6VIRVljtXWNm-0-af05f93d0bff2b725261d681dbd6270f)
要清除全局变量可以用clear命令,命令格式如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P142_29013.jpg?sign=1738883881-jE7iLowqlyFw68eILmFLiPiw084rYF5q-0-57d600ed955978ab4b720c38ebb09e00)
【例3-18】 利用在工作空间和函数文件中定义全局变量,将直角坐标变为极坐标。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P142_29014.jpg?sign=1738883881-nDsTguIS7BhONnkPTELWaMWOfs7W7y3E-0-c06122ffefe670b5b7f88d2defe5d869)
在命令空间输入下面命令,调用函数exam_3_18,结果如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P143_29016.jpg?sign=1738883881-OCYBci12qVWmGATv98MrMbv0KTbRHYIb-0-42ae3c20974b1fae7c5181a2e9570bed)
由于函数exam_3_18和工作空间都定义了a和b为全局变量,只要在命令窗口修改a和b的值,就能完成直角坐标转换为极坐标,而不需要修改函数exam_3_18文件。
在函数文件里,全局变量的定义语句应放在变量使用之前,一般都放在文件的前面,用大写字符命名,以防止重复定义。