1、第5章 MATLAB程序设计 M文件简介 MATLAB程序控制结构 函数调用和参数传递,MATLAB有两种工作方式: (1)交互式的命令行工作方式通常matlab以指令驱动模式工作,即在matlab 窗口下当用户输入单行指令时,matlab 立即处理这条指令,并显示结果,这就是matlab命令行方式。,(2)M文件的程序工作方式较多的命令 重复输入将要输入的所有指令按顺序放到一个扩展名为“.m”的文本文件中,每次运行时只要输入M文件的文件名即可。这种工作模式称为M文件的程序工作方式。,5.1 M文件简介用MATLAB语言编写的程序,称为M文件。,5.1.1 M文件的建立与编辑 M文件是一个文本
2、文件,它可以用任何编辑程序来建立和编辑,而一般常用且最为方便的是使用MATLAB提供的文本编辑器。,输入M文件的内容并存盘。,方法二:命令操作在MATLAB命令窗口输入命令edit,启动MATLAB文本编辑器后,输入M文件的内容并存盘。,方法三:命令按钮操作单击MATLAB主窗口工具栏上的New M-File命令按钮 ,启动MATLAB文本编辑器后,输入M文件的内容并存盘。,注意:M文件的存放位置默认情况下是MATLAB安装目录下的work子目录。,2、编辑已有的M文件 方法一: 菜单操作File Open Open对话框 M文件,方法二: 命令操作 在MATLAB命令窗口输入命令:edit
3、文件名,MATLAB提供了两种源程序文件格式:脚本文件和函数文件,这两种文件的扩展名均为“.m” 。M脚本(Scripts)文件(命令行文件):没有输入参数,也不返回输出参数;M函数(Functions)文件:既可以有输入参数、输出参数,也可以没有输入参数、输出参数。,5.1.2 M脚本文件和M函数文件,一、M脚本文件(命令行文件),本质:是一串指令的集合,与在命令窗口逐行执行文件中的所有指令,其结果是一样的。将需要运行的命令编辑到一个命令文件中,然后在MATLAB命令窗口直接输入该命令文件的名字(执行方法),就会顺序执行命令文件中的命令,该文件称为脚本文件。,(1)脚本文件中的命令格式和前后
4、顺序,与在命令窗口中输入的指令无区别; (2)与在命令窗口中直接运行命令一样,脚本文件产生的变量都驻留在MATLAB的workspace中,可以方便查看变量;脚本文件可以直接访问workspace中的所有数据; (3)文件的文件名要避免与MATLAB内置函数与工具箱中的函数重名,并要放在搜索路径内。,例1:建立一个脚本文件,将变量a、b的值互换。 解:建立li1.m文件 a=1:9; b=11 12 13; 14 15 16; 17 18 19; c=a; a=b; b=c; a b,指令窗口执行该程序 li1 a =11 12 1314 15 1617 18 19 b =1 2 3 4 5
5、6 7 8 9,二、M函数文件函数文件(Function file)是另一种形式的M文件,每一个函数文件都定义一个函数。 1. 脚本文件和函数文件的区别: (1)M脚本文件不需要输入任何参数,也不返回任何参数,主要是为了解决在命令窗口中反复输入命令的繁琐操作;M函数文件通常包含输入参数,也可以返回输出参数,主要解决参数传递和函数调用的问题。 (2)脚本文件对workspace中的变量进行操作;函数文件的变量为局域变量,只有其输出的变量保存在workspace中。,2. 函数文件格式function 输出形参表=函数名(输入形参表)函数帮助信息行函数体是函数的功能实现部分,特定规则: m函数文件
6、第一行必须以单词function作为引导词; 函数信息行:给出函数的帮助信息,帮助信息要从%开头,并放在一行的开头,用help+函数名可查询到;, 函数名的命名规则与变量名相同;m函数文件的文件名可以直接用函数名.m,也可以与函数名不同,但是调用时使用文件名; 当函数的输出形参多于1个时,应用方括号,参数之间用逗号隔开:function a,b=mfile(x,y);当函数无输出参数时,输出参数项应为空,或者用空的中括号表示:function mfile(x,y) 或者function =mfile(x,y); 函数执行后,只保留最后的返回结果,不保留任何中间过程。程序中的变量均为局部变量,不
7、保存在工作空间中,其变量只在函数运行期间有效,随函数调用的结束而从工作空间消除。,解:首先建立函数文件li2.m。函数文件的内容:function li2%ab互换a=1:9; b=11 12 13; 14 15 16; 17 18 19;c=a;a=b;b=c;ab,例2:建立一个函数文件,将变量a、b的值互换。,例3:建立函数文件,将华氏温度f转换为摄氏温度c 解:首先建立函数文件f2c.m。函数文件的内容:function c=f2c(f)c=5*(f-32)/9 f2c(100)c =37.7778,5.2 MATLAB程序控制结构 5.2.1 条件分支结构 条件分支结构根据一定条件来
8、执行的各条语句。 1if语句(1) 单分支if语句:if 条件语句组end当条件成立时,则执行语句组,执行完之后继续执行if语句的后继语句,若条件不成立,则直接执行if语句的后继语句。,(2) 双分支if语句:if 条件语句组1else语句组2end当条件成立时,执行语句组1,否则执行语句组2,语句组1或语句组2执行后,再执行if语句的后继语句。,(3) 多分支if语句:if 条件1语句组1elseif 条件2语句组2elseif 条件m语句组melse语句组nend,function y=shuru(x)if x=1y=2*x.2+1elseif (x-1)y=0elsey=-x.3end,
9、例5:编程判断一年是否是闰年 function leapyear(year) %使用该程序判断是否是闰年 sign=0; if mod(year,4)=0sign=0; elseif mod(year,400)=0sign=1; elseif mod(year,100)=0sign=0; elsesign=1; end if sign=1fprintf(%4d year is a leap year!n,year) elsefprintf(%4d year is not a leap year!n,year) end,执行结果: leapyear(1904) 1904 year is a le
10、ap year! leapyear(1900) 1900 year is not a leap year!,2、Switch语句如果在一个程序中,必须针对某个变量不同取值情况进行相应操作,switch语句比if语句更方便。switch语句用于实现多重选择。,语法:switch 分支条件(函数、变量、表达式)case 条件1(标量、字符串)执行语句1case 条件2 条件3 条件4执行语句2case otherwise 执行语句nend,例6:编写函数文件,将百分制成绩转换为五级制的成绩 function f=trangrade(x) switch fix(x/10)case 10 9f=A;c
11、ase 8f=B;case 7f=C;case 6f=D;otherwisef=E; end,运行结果: trangrade(97) ans = A trangrade(67) ans = D trangrade(55) ans = E,例7 某商场对顾客所购买的商品实行打折销售,标准如下(商品价格用price来表示): price200 没有折扣200price500 3%折扣500price1000 5%折扣1000price2500 8%折扣2500price5000 10%折扣5000price 14%折扣输入所售商品的价格,求其实际销售价格。,function shurujiage(
12、price) switch fix(price/100) case 0,1 %价格小于200rate=0;case 2,3,4 %价格大于等于200但小于500rate=3/100;case num2cell(5:9) %价格大于等于500但小于1000rate=5/100;case num2cell(10:24) %价格大于等于1000但小于2500rate=8/100;case num2cell(25:49) %价格大于等于2500但小于5000rate=10/100;otherwise %价格大于等于5000rate=14/100; end price=price*(1-rate) %输
13、出商品实际销售价格,5.2.2 循环结构 1. while循环while循环以不定的次数重复执行一组语句。语法为:while 逻辑表达式循环体语句endwhile语句执行过程,只要表达式里面的所有元素为真,就执行while和end之间的语句,否则就结束循环。在设计while循环时,应在循环体内有修改“逻辑表达式”的部分,确保执行了一定次数后可以退出循环。,例8:用while循环求1100间整数的和sum=0;i=1;while i=100sum=sum+i;i=i+1;endsumsum =5050,例9:编写函数文件求小于自然数n的婓波纳契数列各项。该数列是一整数数列,其中每个数等于前面两数
14、之和。 function f=fbnq(n) %计算婓波纳契数列各项 f=1 1; i=1; while f(i)+f(i+1) fbnq(30) ans =1 1 2 3 5 8 13 21,2. for循环for循环允许一条或者一组语句被重复执行预先指定的次数。for循环的语法为:for 循环变量=表达式1:表达式2:表达式3循环体end 说明:表达式1的值为循环变量的初值,表达式2的值为步长,表达式3的值为循环终值,当步长为1时,可以省略。表达式的值可以是正整数、负整数或者小数。循环次数如何计算?,例10:使用for循环计算 以及I!(I=1:10)的值。,解:编写脚本文件forsum.
15、m sum=0; part=1; for i=1:10part=part*i;fprintf(part(%d)=%dn,i,part) sum=sum+part; end fprintf(sum=%dn,sum),运行结果: forsum part(1)=1 part(2)=2 part(3)=6 part(4)=24 part(5)=120 part(6)=720 part(7)=5040 part(8)=40320 part(9)=362880 part(10)=3628800 sum=4037913,5.2.3 试探结构试探式语句给用户提供了一种错误捕获机制,可以将编译系统发现的错误捕获
16、,控制对发生的错误进行处理。其格式为:try语句段1catch语句段2end 说明:本语句结构首先试探性执行语句段1,若发现错误,将错误信息赋给lasterr变量,并放弃执行语句段1,转而执行语句段2中的语句。,例11:编写矩阵乘法计算,如有语法错误,给出错误信息, X=magic(4); Y=ones(4,3); try Z=X*Y catch fprintf(not conformable.) endZ =34 34 3434 34 3434 34 3434 34 34, X=magic(4); Y=ones(3); try Z=X*Y catch fprintf(not conforma
17、ble.n) endnot conformable. lasterr ans = Error using = mtimes Inner matrix dimensions must agree.,5.2.4 人机交互命令 1. break命令break使用在循环语句中,一般通过if语句来调用break,从而使系统跳出循环。,%鸡兔同笼,头36,腿100,问有鸡兔各几只 i=1; while 36-i0if i*2+(36-i)*4=100break;endi=i+1; end fprintf(The number of chickens is %dn,i); fprintf(The numbe
18、r of rabbits is %dn,36-i);,2. continue命令continue使用在循环语句中,作用是结束本次循环,即跳过循环体中下面尚未执行的语句,接着执行下一次循环。,%请列出110之间的奇数 for i=1:10if mod(i,2)=0continueendfprintf(%4d,i); end fprintf(n);,执行结果 continue_exam1 3 5 7 9,3. input命令提示用户从键盘输入数值、字符串和表达式,并接受该输入。 调用格式: A=input(提示信息,选项) 说明: (1)A=input(statement):在屏幕上显示state
19、ment,等待用户输入,并将数值赋给A; (2)A=input(statement,s):将输入作为字符串,而不是数值赋给变量; (3)如果没有任何输入字符,而只按回车键,将返回一个空矩阵。n则表示换行输出。,例12:计算一元二次方程ax2+bx+c=0的根 a=input(a=?n); b=input(b=?n); c=input(c=?); d=b2-4*a*c; x=(-b+sqrt(d)/(2*a) (-b-sqrt(d)/(2*a) 执行结果: input_exam a=? 1 b=? 2 c=?3 x =-1.0000 + 1.4142i -1.0000 - 1.4142i,4.
20、pause命令该命令的作用是暂停程序的执行,适用于程序调试时,查看中间结果的情况。 调用格式: pause(延迟秒数) 说明: (1)pause:使程序运行停止,等按任意键继续运行; (2)pause(n):在继续执行前中止执行程序n秒; (3)pause on:允许后续的pause命令中止程序的运行; (4)pause off:保证后续的pause或pause(n)命令都不中止程序的运行。,例13:pause函数使用说明 function pause_exam t=0:0.05:3*pi; x=sin(t); y=cos(t); plot(t,x); pause plot(t,y); pau
21、se(3); plot(t,x+y);,5. disp命令该命令的作用是命令窗口输出字符串或矩阵。 调用格式: disp(输出项),例14: 输入x,y的值,并将它们的值互换后输出。程序如下:x=input(Input x please.);y=input(Input y please.);disp(xy值互换)z=x;x=y;y=z;disp(x);disp(y);,6. keyboard命令在M文件中请求键盘输入命令,可以通过输入return并按回车以中止keyboard模式。 K return 7. error语句 调用格式:error(message)显示错误信息,并将控制权交给键盘,
22、显示message。如果message是空,则error命令将不起作用。,例15:编写程序求解一元二次方程,如果根为复数,输出错误信息,并不输出计算结果。 function error_test(a,b,c) %解方程a*x2+b*x+c=0 d=b2-4*a*c; if d error_test(1,2,3) ? Error using = error_test The roots are complex! error_test(1,4,3) x =-1 -3,5.3 函数调用和参数传递 5.3.1 函数的类型 1. 匿名函数匿名函数是不需要M文件,只包含一个MATLAB表达式,任意多个输入
23、和一个输出,可以在命令窗口、M文件中定义,其语法为:f=(arglist)expression 说明: (1)expression是该函数的函数体,arglist是输入参数列表; (2)匿名函数可以具有多个输入参数,如sum=(x,y)(3*x+4*y)。, t=()disp(Good Afternoon!); t() Good Afternoon! squ=(x)x2 squ = (x)x2 squ(10) ans =100 sumAxBy=(x,y)2*x+4*y; sumAxBy(2,4) ans =20,2. 主函数和子函数 主函数和子函数的区别: (1)MATLAB允许一个M函数文件
24、包含多个函数的代码,其中第一个出现的函数称为主函数,其余的函数为子函数。 (2)保存时所用的函数名称与主函数定义名相同。 (3)主函数可以在M文件外部调用,而子函数不行。(4)同一文件的主函数和子函数的工作空间是相互独立的。,例16:编写一函数,要求输入任意两个数后,求出这两数之和与绝对值之和的积。 function ch=sub(x,y) %主函数 ch=sub1(x,y)*sub2(x,y); function ch=sub1(x,y) %子函数1 ch=x+y; function ch=sub2(x,y) %子函数2 ch=abs(x)+abs(y); 运行结果: sub(4,3) an
25、s =49 sub(4,-3) ans =7,5.3.2 局部变量和全局变量 1. 局部变量(Local Variables)局部变量是在函数体内部的变量,其影响范围是本函数内部,而且不加载到MATLAB的工作空间。局部变量只在函数执行期间存在,当函数执行完变量就消失。 2. 全局变量(Global Variables)全局变量是可以在不同的函数工作空间和MATLAB工作空间中共享使用的变量。在使用前必须用global定义,而且在任何使用该变量的函数中都要加以定义,即使在命令窗口中也不加以例外。,function f=global_exam(x,y) % define 2 global var
26、iables global A B f=A*x+B*y; 在命令窗口中输入 global A B A=1; B=2; f=global_exam(2,3) f =8,5.3.3 函数的参数 1. 函数的调用 函数的调用方式: 输出实参表=函数名(输入实参表) 2. 函数参数的个数 nargin:该函数输入实参的个数 nargout:该函数输出实参的个数,例17:编程实现,若只输入一个变量,系统提示输入错误,若输入两个、三个变量,则将各变量相加,将和输出。 function f=nargintest(a,b,c) if nargin=1error(Not enough input arguments); elseif nargin=2f=a+b; elseif nargin=3f=a+b+c; end, nargintest(1) ? Error using = nargintest Not enough input arguments nargintest(1,2) ans =3 nargintest(1,2,3) ans =6 nargintest(1,2,3,4) ? Error using = nargintest Too many input arguments.,