![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=1739579628-BWpThQ09VrirqRn5lmoG6IToI99VaYCC-0-3a8f9a335d86d6a326a14936b60ac953)
其中,以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=1739579628-yi0WtxDbPEoCYt0DCY0WbajDzipybxQ1-0-77b760dff36b2a270dc6fddfd2ddbc7e)
由以上结果可知,lookfor命令只显示注释的第一行信息,而help命令显示所有注释信息。
如果用lookfor命令查询perimeter关键字,可以查询到已经编写过的有关周长perimeter的函数文件,如下所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P135_28987.jpg?sign=1739579628-UlKVDLNmC88bRDvzZUZjTrl0kCJZo1Ik-0-59dbe8eb2a82935e369e5db0b6c5ed59)
3.3.2 M函数文件的调用
M函数文件编写好后,就可以在命令窗口或者M脚本文件中调用函数。函数调用的一般格式如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P135_28988.jpg?sign=1739579628-RyG1XtYUEeRrkvz253zLhXnIeClolwUY-0-fc31deed98c4c39ca89544a7ccfbe201)
需要注意,函数调用时各实参数列表出现的顺序和个数,应与函数定义时的形参列表的顺序和个数一致,否则会出错。函数调用时,先将输入实参数传送给相应的形参数,然后再执行函数,函数将输出形参数传送给输出实参数,从而实现参数的传递。
【例3-15】 编写函数文件,实现极坐标(ρ,θ)与直角坐标(x,y)之间的转换。
已知转换公式为
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28991.jpg?sign=1739579628-EqxnTtwKlwNBDZmlDEybE66KbRHbB3S4-0-695232cab9c40d30c3a4f20ae8fa5993)
函数文件ftran.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28992.jpg?sign=1739579628-WEuUHUfhvecW9gWOwBB6zQhjj2tsPfzx-0-7a22112f43aefc6488e81aaae3aa598e)
在命令窗口可以直接调用函数文件ftran.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28993.jpg?sign=1739579628-rAZ6HvInUGWtK39giFQWVmRUvlsq50qT-0-adbdd15b977bec171ec2a9358c137f32)
也可以编写调用函数文件ftran.m的M脚本文件exam_3_15.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28994.jpg?sign=1739579628-LqYiWdOrCVSjMxzvzrrNug78rEWNRrXW-0-7924100e8b27e54b2d37e6e6fbefc65c)
运行M脚本文件exam_3_15.m,结果如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28995.jpg?sign=1739579628-2dabeIFSTNkpKKrTk2pdbXbQK6Zg2U19-0-869fe888bb54515e20cc773cbeb7cbb8)
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=1739579628-VgUd3q3HzarNnXctNyqlCOnvahJmxnZX-0-52046c8cfac0124635b73b814a04daf5)
M函数文件exam_3_16.m如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P137_28997.jpg?sign=1739579628-GSGqppkeELBiLlMOSY36FRXShpwe7fi7-0-93aa964b854b43be1adb84d7a96e873a)
在命令窗口直接调用函数文件exam_3_16.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P138_28999.jpg?sign=1739579628-1eshJHQwwQFlKhNUkqqjLJ1OFpsHswAf-0-1dc4ba72097f9e19795e828f3f1c3b68)
结果如图3-9所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P138_9528.jpg?sign=1739579628-ttaFAJcXf4oeebLUQrUFZ7v6ebO3H40O-0-e8a22b0ce196d7ae693eaa533f7ecbce)
图3-9 ax2+bx+c曲线(z=1)
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P138_29000.jpg?sign=1739579628-AeVDG8IrmuTCQPj3mJnvvtjfybJYQCV6-0-8d6fe8312bdcc579b05e40fe9256040f)
结果如图3-10所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P138_29001.jpg?sign=1739579628-MzLoKpGWRffpYuHraKkpYM6BUoMXCB2b-0-80bc9839c0b5c5bbb1798c4abb85479d)
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P139_9548.jpg?sign=1739579628-zucXDhMDzvjuXiWa97OobuiZnuDRDW91-0-4377d0f87d4ee5dbef99f58de425cef8)
图3-10 asin(x)+b曲线(z=2)
结果如图3-11所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P139_9552.jpg?sign=1739579628-bofJ1APP0lB4pvnMeoNAR7NYa4QZUTuX-0-db0754bdfacf4bf9f37b8e7477ccdf66)
图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=1739579628-MGm5HddGlTzj3PSpfrrjSRjAb3EZSkBA-0-c551ee8ebd7a2a5f195f0cc9863657c0)
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=1739579628-yrBzpOrVJIL51JCB8QIK4xadQbOnCgdx-0-905652a950caf6ce9ea361a0bf75a263)
可知,将变量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=1739579628-7BnZhDMnVWmRdvDIIF1X9XAU0ghPGRlw-0-cbb78e9ee222c651500e82d1edc63851)
其中,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=1739579628-YSbxxf9q23jWMJgHVSbP3RAP0qbHtD13-0-de15a234cd6d4a2180c359af2873078a)
(2)MATLAB提供了varargin和varargout函数,将函数调用时实际传递的参数构成元胞数组,通过访问元胞数组中各元素的内容来获得输入和输出变量。varargin和varargout函数的格式如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P141_29009.jpg?sign=1739579628-JEVX9UpF8bPTL22O86WZnv53HmtnfSyC-0-a9c81719998eebacfc38dfcd5eaeb8d6)
【例3-17】 根据输入参数的个数使用varargin和varargout函数,绘制sin(x)不同线型的曲线。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P141_29010.jpg?sign=1739579628-ZbWPMHWaVHOOhHNgjZ2PmhtSC8F9Ayu5-0-e5c7056b2ffffd0c5792336c763e7c02)
在MATLAB命令空间输入下列命令,执行该函数,显示的曲线如图3-12所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P141_29011.jpg?sign=1739579628-ypyL0ZzTFv1nyG5LZ88iyJqF9i1sg4UT-0-cb79332573b82baf12d59beffb379380)
需要注意,varargin和varargout函数获得的都是元胞数组。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P142_9626.jpg?sign=1739579628-bxFbHUyVf2S6tSOvjGmqQajoowyCNdTf-0-f09ba195fb491c5d7a6ca9299f6ef949)
图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=1739579628-DMWJgKrdxhZCh2F8QnzcFk04xVQE8vef-0-764c7dad8d7c573469cfc96a2eccaa6a)
要清除全局变量可以用clear命令,命令格式如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P142_29013.jpg?sign=1739579628-nvwLRFr5TYMVwYoHbrwqxkuj5YAlWBQG-0-b102896e6941e1882e0a26c450a3c2fc)
【例3-18】 利用在工作空间和函数文件中定义全局变量,将直角坐标变为极坐标。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P142_29014.jpg?sign=1739579628-YFh2KqH0Xh5ID7taP1ihWKXujvNFqLRN-0-4450d52370b61a780ca9822e28c4f9ec)
在命令空间输入下面命令,调用函数exam_3_18,结果如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P143_29016.jpg?sign=1739579628-LuEsb3Bm1oCz5oeMeyJRCdPWbq0JFctO-0-8eed355f5446c11b21d183ebb22b4491)
由于函数exam_3_18和工作空间都定义了a和b为全局变量,只要在命令窗口修改a和b的值,就能完成直角坐标转换为极坐标,而不需要修改函数exam_3_18文件。
在函数文件里,全局变量的定义语句应放在变量使用之前,一般都放在文件的前面,用大写字符命名,以防止重复定义。