![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=1738890764-sfnRREL9IK3XtNwzqqKLnABMsT9hRV6j-0-c0a84ef0790f50d5b78cc2adc58eb82d)
其中,以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=1738890764-nALhnGHpunUfw8BGMR2EIlg2XO0eGCjf-0-d3a420d81d5792a4be93205e408c2881)
由以上结果可知,lookfor命令只显示注释的第一行信息,而help命令显示所有注释信息。
如果用lookfor命令查询perimeter关键字,可以查询到已经编写过的有关周长perimeter的函数文件,如下所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P135_28987.jpg?sign=1738890764-hXT7Ph2dpGFcc2mB38fTQCQCHNCJ5A9d-0-b3130dc10de3f549731b16dbf1a93826)
3.3.2 M函数文件的调用
M函数文件编写好后,就可以在命令窗口或者M脚本文件中调用函数。函数调用的一般格式如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P135_28988.jpg?sign=1738890764-BVcaWPgF5YeLpjsdnAyESYvOJmkuOK7E-0-bc8aefca3d8ae384e81f9f2607ea7d34)
需要注意,函数调用时各实参数列表出现的顺序和个数,应与函数定义时的形参列表的顺序和个数一致,否则会出错。函数调用时,先将输入实参数传送给相应的形参数,然后再执行函数,函数将输出形参数传送给输出实参数,从而实现参数的传递。
【例3-15】 编写函数文件,实现极坐标(ρ,θ)与直角坐标(x,y)之间的转换。
已知转换公式为
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28991.jpg?sign=1738890764-yjv4LjnZqhzeICHjLJvniS6wdZb3EiUD-0-fbe5e4c34ce01cfde6202ff7db72a224)
函数文件ftran.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28992.jpg?sign=1738890764-w2F3n5YPyIqGasDwuv3wViZjwoDzVhIt-0-ccb6c43581b8aa4ddb62c6e851745824)
在命令窗口可以直接调用函数文件ftran.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28993.jpg?sign=1738890764-qFymXUIpZFpDFPstAE5QPNx9bwPkVUlS-0-1d0cf8a274361711bc4d6f544e8077dc)
也可以编写调用函数文件ftran.m的M脚本文件exam_3_15.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28994.jpg?sign=1738890764-Op5HH7zgScVXkjXwB1EgIX8tPgIZOAXj-0-988322addb2dd04a9135ca269a51eb65)
运行M脚本文件exam_3_15.m,结果如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P136_28995.jpg?sign=1738890764-pmeXRZ4oDXTC8xtrNXGGeKOuCw3wokdE-0-6b5141681ca45dfc4d37cd79e2e067f4)
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=1738890764-AQUKjQaubJEQ8kNiA2bBPuq3iGxqVzQT-0-b27392d53fc2584db182c72d450d8d78)
M函数文件exam_3_16.m如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P137_28997.jpg?sign=1738890764-TmDQkFUhTGgZrkkt4F3YffVK9FnemnIA-0-1d7f1c8f9f8fac8473cce9f1550be7d8)
在命令窗口直接调用函数文件exam_3_16.m:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P138_28999.jpg?sign=1738890764-VQoiGCM0uGqhyf2biXtW61mKSh8FJxir-0-82a869053ec2783867370d4378eac571)
结果如图3-9所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P138_9528.jpg?sign=1738890764-42qgoHQ9Ho2unSW0zIiP9kpKdLicATAB-0-b9ba87413e96bfcdbd2a2de3cd2ecae6)
图3-9 ax2+bx+c曲线(z=1)
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P138_29000.jpg?sign=1738890764-xBliwVi3wrgxknlgN6ANqHhlOh9uzvQY-0-93e3ca3ad3165fd5c74c3a4b0c4a4354)
结果如图3-10所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P138_29001.jpg?sign=1738890764-VvFgj4y9t1DnnQHg3LBEWz9jQcrUTBUi-0-efeb5b82f1538867539a922845cd3084)
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P139_9548.jpg?sign=1738890764-sDiql7X8aC9WmaV8L5Sc4KbVqWFCro7J-0-4cf933263d75f634fb34d8d3bfd3ffcd)
图3-10 asin(x)+b曲线(z=2)
结果如图3-11所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P139_9552.jpg?sign=1738890764-vGdhvB1WCShbsJ48pXoAqjjMwQJ1TmkI-0-d8d3817c69d57eafbe89e420944204b4)
图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=1738890764-amsklpXtGaGOopRwGly05Q35O3cr0ZPx-0-afd0d41e6e7be03ad688a2b0516cbbdf)
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=1738890764-yGGLfQxNDZUXgKtcf5cFjAeZJMp3O91x-0-feac90aef8f8f9d8992cb72172d84b41)
可知,将变量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=1738890764-jrMlN7s00Uzbhx3JxoflyhgDmN8qzEEi-0-8db3454327500e11723003cc620488a7)
其中,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=1738890764-GpGb4UoWiyt9JEgTGGk4b2mZOL4dn6l0-0-af3f5d8d27b897bdb41a12bfa8b950b4)
(2)MATLAB提供了varargin和varargout函数,将函数调用时实际传递的参数构成元胞数组,通过访问元胞数组中各元素的内容来获得输入和输出变量。varargin和varargout函数的格式如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P141_29009.jpg?sign=1738890764-8j9PykT59hcNv5J7KtOglS6DtCofMioe-0-68c59f3e77b3df19999c07fdcece9c1c)
【例3-17】 根据输入参数的个数使用varargin和varargout函数,绘制sin(x)不同线型的曲线。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P141_29010.jpg?sign=1738890764-6GcvdG5W3rNtmDCoi9o9D9ceFtV7470b-0-022a9fa9f8f51e6bcf336bfa72d7aa6b)
在MATLAB命令空间输入下列命令,执行该函数,显示的曲线如图3-12所示。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P141_29011.jpg?sign=1738890764-pnPxzoo4xU54lNjjspaprKpjiCaE1dy6-0-a33fdb271a00525b887b852486361c27)
需要注意,varargin和varargout函数获得的都是元胞数组。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P142_9626.jpg?sign=1738890764-ObXZPDH62X7tXCGHt0H1ecaPGFdmuFPM-0-2d3ac39fb9c5623770a2a85bbf321b7e)
图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=1738890764-dqrouyP3lD0iJYco6lxJIaMpjENFjg9K-0-0f9edf297060161e48d9718fd9c98329)
要清除全局变量可以用clear命令,命令格式如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P142_29013.jpg?sign=1738890764-CHi858f8IzczEYV2bHn3a133gvvXc7bT-0-89565c7be1e691e59504c6c97c46b2c8)
【例3-18】 利用在工作空间和函数文件中定义全局变量,将直角坐标变为极坐标。
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P142_29014.jpg?sign=1738890764-4cznDzrFpDs6Bmpp4C2egQuLyeOWkvKz-0-64ed205756453814c3849d2ed16e4f49)
在命令空间输入下面命令,调用函数exam_3_18,结果如下:
![](https://epubservercos.yuewen.com/59B7C6/15477655505633306/epubprivate/OEBPS/Images/Figure-P143_29016.jpg?sign=1738890764-iqzPPqCHhH94MdVUuwzG92KymNPFbZVD-0-c8de0a96f7151f66de82b639b16fcb35)
由于函数exam_3_18和工作空间都定义了a和b为全局变量,只要在命令窗口修改a和b的值,就能完成直角坐标转换为极坐标,而不需要修改函数exam_3_18文件。
在函数文件里,全局变量的定义语句应放在变量使用之前,一般都放在文件的前面,用大写字符命名,以防止重复定义。