第六章 m 文件和函数句柄

46
第第第 M 第第第第第第第 —— matlab 语语语语语语 语语语语语 语语语语语 语语语语语语语语语语 ,、 语语语语语语语语语语 m 语语语 matl ab 语语语语语语

Upload: brina

Post on 27-Jan-2016

56 views

Category:

Documents


0 download

DESCRIPTION

第六章 M 文件和函数句柄. —— matlab 语言称为第四代编程语言,程序简洁、可读性很强而且调试十分容易。 进行程序设计的 m 文件是 matlab 重要组成部分。. 本章内容 §1 matlab 控制流 §2 脚本文件和函数文件 §3 函数类别 §4 函数句柄. 6.1 MATLAB 控制流. (1) 顺序结构 —— 依次顺序执行程序的各条语句 (2) 分支结构 —— 根据一定条件来执行各条语句。 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第六章   M 文件和函数句柄

第六章 M文件和函数句柄

—— matlab 语言称为第四代编程语言,程序简洁、可读性很强而且调试十分容易。

进行程序设计的 m 文件是 m

atlab 重要组成部分。

Page 2: 第六章   M 文件和函数句柄

本章内容 §1 matlab 控制流 §2 脚本文件和函数文件 §3 函数类别 §4 函数句柄

Page 3: 第六章   M 文件和函数句柄

6.1 MATLAB 控制流 (1) 顺序结构 —— 依次顺序执行程序的各条语句(2) 分支结构——根据一定条件来执行各条语句。

if — else — end 条件控制语句有 3 种形式 单分支 、双分支、多分支 switch — case — otherwise — end 结构 仅执行满足条件的分支 (3) 循环结构 —— 被重复执行的一组语句。 循环语句主要有: for — end while — end

Page 4: 第六章   M 文件和函数句柄

分支控制有 3 种形式 多分支 if 表达式 1 语句 1 elseif 表达式 2 语句 2 elseif 表达式 3 语句 3 · · · else 语句 n end

6.1 MATLAB 控制流 6.1.1 if — else — end条件控制

单分支 if 表达式 执行语句 end 双分支 if 表达式 语句 1 else 语句 2 end

Page 5: 第六章   M 文件和函数句柄

• 在条件表达式中,通常用

关系操作符 : >, < ,<=, >=, = =, ~=

逻辑操作符 : & , | , ~

逻辑函数: isequal —— 若是相等则为真

isempty —— 若是空矩阵则为真

isstr —— 若是字符串则为真

Page 6: 第六章   M 文件和函数句柄

function y=abc(x)% function calculate of yn=length(x);for k=1:n if x(k)<-1 y(k)=x(k); elseif x(k)>=1 y(k)=exp(1-x(k)); else y(k)=x(k)^3; endend

例 6.1-1 :编写 m 函数,对于任意一组输入 x 值,计算函数值 x (x<-1)

y = x3 (-1≤x<1)

e-x+1 (x≥1)

x=[-2,-1.2,-0.4,0.8,1,6]y=abc (x) x = -2.0000 -1.2000 -0.4000 0.8000 1.0000 6.0000y = -2.0000 -1.2000 -0.0640 0.5120 1.0000 0.0067

Page 7: 第六章   M 文件和函数句柄

switch-case 语法结构: switch expr case value1 (commands 1) case value2 …… case vlauek (commands k) otherwise (commands) end

6.1.2 switch-case 控制结构

Page 8: 第六章   M 文件和函数句柄

● 当遇到 switch 结构时 , matlab 将表达式的值依次和各个 case指令后面的检测值进行比较 . 如果比较结果为假 , 则取下一个检测值再比较 , 一旦比较结果为真 , matlab 将执行相应的一组命令 , 然后跳出该结构。如果所有的比较结果都为假 , 即表达式和所有的检测值都不等 , matlab 将执行 otherwise 后面的一组命令 . 可见该结构保证至少有一组命令会得到执行。

●switch 指令后面的表达式为一个标量或者一个字符串。对于标量形式的表达式 , 比较这样进行 : 表达式 == 检测值 i. 对于字符串 ,将调用函数 strcmp 来实现比较。

●case 指令后面的检测值不仅可以是一个标量值或字符串,还可以是一个单元数组。如果一个检测值是一个单元数组, matlab 将把表达式的值和该单元数组中的所有元素进行比较,如果单元数组中某个元素和表达式的值相等,就认为此次比较结果为真。

● 当 matlab 检测到某个检测值和表达式相等时,将执行相应的一组命令,执行完毕,自动跳出 swith 结构,无需使用 break 指令。

Page 9: 第六章   M 文件和函数句柄

例 6.1-2 :根据学生百分制分数进行等级成绩划分 .for i=1:10 a{i}=89+i; b{i}=79+i; c{i}=69+i; d{i}=59+i; end % 用胞元数组c=[d,c];A=cell(2,5); A(1,:)={'Jack','Marry','Peter','Rose','Tom'};A(2,:)={72,83,56,94,100}; % 用胞元数组for k=1:5 switch A{2,k} case 100, A{3,k}= ' 满分 '; case a, A{3,k}= ' 优秀 '; case b, A{3,k}= ' 良好 '; case c, A{3,k}= ' 及格 '; otherwise, A{3,k}= ' 不及格 '; endendA

'Jack' 'Marry' 'Peter' 'Rose' 'Tom'

[ 72] [ 83] [ 56] [ 94] [ 100]

' ‘及格 ' 良好 ' ' 不及格 ' ' ‘优秀 ' 满分 '

Page 10: 第六章   M 文件和函数句柄

例 6.1-3 :用 for 循环生成 Hilbert 方阵 ( )

循环法 : K=5; A=zeros(K,K);% 预配置内存空间 for m=1:K for n=1:K A(m,n)=1/(m+n-1); end end format rat A

6.1.3 for 循环和 while 循环

)1/(1),( jijia

向量法 :

N=5;

n=repmat(1:N,N,1);

m=n';

format rat

A3=1./(n+m-1)

for 循环结构语法为: for i = 表达式 (表达式为一个向量) 可执行语句 end

Page 11: 第六章   M 文件和函数句柄

while — end 循环结构语法为: while 表达式 循环体语句 end

表达式一般是由逻辑运算和关系运算以及一般运算组成的,以判断循环的进行和停止;只要表达式的值非 0 ,继续循环;直到表达式值为 0 ,循环停止。可借助 break 指令退出循环。

Page 12: 第六章   M 文件和函数句柄

例 6.1-4:计算 为给定精度其中 }.1min{arg,

1

1

1

1

N

k

N

nn

k

kN

kS

调用 :>>[S,N]=exm060104(0.0001) S = 1.9859, N = 141

function [S,N]=exm060104(epsilon)k=0;s=0;d=inf;S=0;while d>epsilon k=k+1; s=s+k; %sum(1:k)

d=1/s; S=S+d;endN=k;

符号法验证结果 :N=141;SN=vpa(symsum(1/symsum(k,1,n),n,1,N)) %N项 (141项 )

和 SN=1.9859154929577464788732394366197syms k n NSINF=limit(symsum(1/symsum(k,1,n),n,1,N),N,inf) SINF=2

Page 13: 第六章   M 文件和函数句柄

【例 6.1-5】创建 n阶魔方矩阵,限定条件是 n为能被 4整除的偶数。( 1)所谓魔方矩阵(Magic matrix),是指那矩阵由 1 到 n2 的正整数按照一定规则排列而成,并且每列、每行、每条对角线元素的和都等于 n(n2+1)/2 。就生成规则而言,魔方矩阵可分成三类:一, n为奇数;二,n为不能被 4整除的偶数;三, n为能被 4整除的偶数。clear;clc;while 1

n=input('请输入一个能被 4整除的正整数! n = '); if mod(n,4)==0 break endendG=logical(eye(4,4)+rot90(eye(4,4))); m=n/4;K=repmat(G,m,m); N=n^2;A=reshape(1:N,n,n); A(K)=N-A(K)+1

Page 14: 第六章   M 文件和函数句柄

s0=round(n*(n*n+1)/2);disp([int2str(n),' 阶魔方矩阵的标称和是 ',int2str(s0)])Ns0=round(2*(n+1));B=A';SC=sum(A); SR=sum(B);Sd=sum(diag(A)); Sdi=sum(diag(B)); LS=[SC,SR,Sd,Sdi]==s0;

NS=round(sum(LS));if NS==Ns0

disp('经验证, A 是魔方矩阵。 ')else

disp('经验证, A 不是魔方矩阵。 ')end

12 阶魔方矩阵的标称和是 870

经验证, A 是魔方矩阵。

Page 15: 第六章   M 文件和函数句柄

6.1.3 控制程序流的其他常用指令见表 6.1-4

input

keyboard

break

continue

pause(n)

return

Page 16: 第六章   M 文件和函数句柄

控制程序程序流的其他常用指令

1) v=input('msg')

v=input('msg', 's' )

该指令执行时 , 控制权交给键盘 ,待输入结束 ,按 Enter键 , 控制权交换matlab, msg 是提示用的字符串 ,告诉用户输入什么 .

第一种格式用于键入数值 , 字符串等数据 ,最后 v 是一个数值 (包括数组 ) 或者一个字符串.

第二种格式 , 不管键入什么 ,总以字符串形式赋给变量v 。

Page 17: 第六章   M 文件和函数句柄

2) keyboard

从M 文件中激活键盘 , 遇到该命令时,将控制权交给键盘,用户可以从键盘输入各种 matlab 指令,仅当用户输入 return 指令后,控制权才交还给程序。与 input 指令的区别是:该指令允许输入任意多个 matlab 指令, 而 input只能输入赋给变量的值。该指令在调试 M 文件时非常有用。

Page 18: 第六章   M 文件和函数句柄

3) continue

跳过位于其后的循环中的其他指令 , 执行循环的下一个迭代

例 更改数组中的值

a=ones(1,12);count=0;s=0;for k=1:12 if rem(k,3)==0 continue else s=s+k; end count = count + 1; end

count = 8

break

Page 19: 第六章   M 文件和函数句柄

4) break

终止 while,for 循环 ,也可以在 if-end, switch-case, try-catch 中导致中断

5) pause, pause(n)

第一种格式使程序暂停执行 , 等待用户按任意键继续 , 第二种格式使程序暂停 n秒后 , 再继续执行

6) return

结束 return 指令所在函数的执行 , 把控制转至主调函数或指令

窗 .否则 ,只有整个被调函数执行完毕才转出

Page 20: 第六章   M 文件和函数句柄

6.2 脚本文件 和函数文件

脚本文件 — 简单的 m 文件脚本文件实际上是一串指令的集合,与在命令窗口逐行执行文件中的所有指令,其结果是一样的。没有输入输出参数。

运行产生的所有变量驻留在基本工作空间。

6.2.1 脚本文件

m 文件的语法类似于 c 语言,但又有其自身特点。它只是一个简单的 ASCII码文本文件,执行程序时逐行解释运行程序。

m 文件有两类独立的 m 文件 — 称脚本文件 可调用 m 文件 — 称函数文件

Page 21: 第六章   M 文件和函数句柄

6.2.2 M 函数文件— 需要输入变量,返回输出变量

函数 m 文件的格式: function 返回变量 = 函数名(输入变量) %注释说明语句段 程序语句段特定规则:1. 函数 m 文件第一行必须以单词 function 作为引导词,必须遵循如下形式:

function <因变量 >=< 函数名 >(< 自变量 >)

2. m 文件的文件名最好是 < 函数名 > .m 。3. 程序中的变量均为局部变量,不保存在工作空间中。 其变量只在函数运行期间有效。

Page 22: 第六章   M 文件和函数句柄

6.2.3 局部变量和全局变量• 局部 (local)变量– 它存在于函数空间内部的中间变量,产生于该函数

的运行过程中,其影响范围也仅限于该函数本身。• 全局 (global)变量– 通过 global 指令定义变量, Matlab也允许几个不同的函数空间以及基本工作空间共享同一个变量。这种被共享的变量称为全局变量。每个希望共享全局变量的函数或 Matlab基本工作空间,必须逐个用 global 对具体变量加以专门定义。没有采用 global 定义的函数或基本工作空间,将无权享用全局变量。

Page 23: 第六章   M 文件和函数句柄

关于全局变量的说明 如果某个函数的运作使全局变量的内容发生了变化,那么其他函数空间以及基本工作空间中的同名变量也就随之变化。

除非与全局变量联系的所有工作空间都被删除,否则全局变量依然存在。

对全局变量的定义必须在该变量被使用之前进行。建议把全局变量的定义放在函数体的首行位置。

虽然 Matlab 对全局变量的名字没有任何特别的限制,但是为了提高 M 文件的可读性,建议选用大写字符命名全局变量。

由于全局变量损害函数的封装性,因此不提倡使用全局变量。

Page 24: 第六章   M 文件和函数句柄

6.2.4 函数文件一般结构 : 举例 vdp1,ode45

1. 函数申明行 :位于函数文件的首行,以关键字 function开头,函数名以及函数的输入输出参量都在这一行定义。函数名和文件名必须相同。

2.H1 行:紧随函数申明行之后以 %开头的第一行注释行,包括大写体的函数文件名;运用关键词要描述的函数功能。

3. 在线帮助文件文本 : H1 行及其之后的连续 %开头的所有注释行构成整个在线帮助文本。它通常包括:函数输入输出参量的含义,调用格式说明。

Page 25: 第六章   M 文件和函数句柄

6.2.4 函数文件一般结构

4. 编写和修改记录:与在线帮助文本区相隔一个“空”行,也以 %开头。标志编写及修改该文件的作者、日期和版本记录。它用于软件档案管理。

5. 函数体:这部分内容由实现该 M 函数文件功能的 M

atlab 指令组成。它接收输入参量,进行程序流控制,得到输出参量。

Page 26: 第六章   M 文件和函数句柄

例 6.2-1 :根据指定边数 N 、半径、线型色彩,绘出圆周线(正多边形 ) 或填色圆 (正多边形 ) 。

function [S,L]=exm060201(N,R,str)switch nargin case 0, N=100;R=1;str='-b'; case 1, R=1;str='-b'; case 2, str='-b'; case 3 ; otherwise, error(' 输入量太多 ');end;t=0:2*pi/N:2*pi;x=R*sin(t);y=R*cos(t);if nargout==0,plot(x,y,str)elseif nargout>2,error(' 输出量太多 ');else S=N*R*R*sin(2*pi/N) /2; L=2*N*R*sin(pi/N); fill(x,y,str)endaxis equal square,box on,shg % 将该函数 M 文件存于 matlab搜索路径上

调用:[S,L]=exm060201(6,2,'-g')

-1 -0.5 0 0.5 1-1

-0.5

0

0.5

1

Page 27: 第六章   M 文件和函数句柄

function grade=score2grade(score);% TRANS 将学生分数 score 转换为五级制成绩 grade% 级别, 90-100, A; 80-89, B; 70-79,C; 60-69,D; others, E;for i=1:10 a{i}=89+i; b{i}=79+i; c{i}=69+i; d{i}=59+i; endfor k=1:length(score) switch score(k) case 100, grade{k}= ‘A'; case a, grade{k}= ' A '; case b, grade{k}= ‘B'; case c, grade{k}= ‘C'; case d, grade{k}= ‘D'; otherwise, grade{k}= ‘E'; endend

例 6.1-2 存为 M 函数文件 , 百分成绩转换为五级制成绩。

Page 28: 第六章   M 文件和函数句柄

(1) 主函数 :由第一个 function引出的函数(2)子函数 :由非第一个 function引出的 ,寄生在主函数体内的函数

各函数间通过输入输出宗量或全局变量传递(3)匿名函数 : 不以文件形式驻留在文件夹中 创建 :FH=@(arglis)expr

直接调用 :FH(arglis)

用函数句柄演算函数间接调用 :feval(FH,arglis)

6.3 MATLAB 的函数类别

例 : 匿名函数的调用 y=@(x)(x.^2+x-20)

feval(y,2) 或 y(2)

Page 29: 第六章   M 文件和函数句柄

6.3.1 主函数

• 通常每个 M 文件中的第一个函数为主函数,主函数可以被该文件之外的其他函数调用,而子函数只能被该文件内的函数调用。主函数的调用通过存储该函数的 M 文件的文件名调用。我们在前面几节中编写的实验程序,大多为主函数。因此,这里不再过多介绍。

6.3 MATLAB 的函数类别

Page 30: 第六章   M 文件和函数句柄

6.3.2 子函数

一个 M 文件中可以包括多个函数,除主函数之外的其他函数称为子函数。子函数只能被主函数或该文件内的其他子函数调用。每个子函数以函数定义语句开头,直至下一个函数的定义或文件的结尾。

当函数中调用函数时,系统判断其函数类型的顺序为:首先判断是否为子函数,然后判断是否为私有函数,最后判断其是否为当前目录下的 M 文件函数或者系统内置函数。由于子函数具有最高的优先级别,因此,在定义子函数时,可以采用已有的其他外部函数的名称。

Page 31: 第六章   M 文件和函数句柄

子函数– 每个子函数的第一行是其自己的函数申明行;– 主函数的位置不可改变,但子函数的排列次序可以

任意改变;– 子函数只能被处于同一文件的主函数或其他子函数

调用;– 在 M 函数文件中,任何指令通过“名字”对函数进

行调用时,子函数的优先级仅次于内装函数。– 同一文件的主函数、子函数的工作空间都是彼此独立的。各函数间的信息,或通过输入输出宗量传递,或通过全局变量传递,或通过跨空间指令传递。

– help , lookfor 等帮助指令都不提供关于子函数的任何帮助信息。

Page 32: 第六章   M 文件和函数句柄

第四章习题六用主、子函数实现

function y0_5=main( )tspan=[0, 0.5]; y0=[1;0]; [tt,yy]=ode45(@DyDt,tspan,y0); y0_5=yy(end,1); function ydot=DyDt (t,y)mu=3;ydot=[y(2);mu*y(2)-2*y(1)+1];

在命令行输入 y0_5=main ,即可得到结果

Page 33: 第六章   M 文件和函数句柄

例 6.3-1: 编写一个内含子函数的函数 M 文件function Hr=exm060301(flag)%------prime function-----------t=(0:50)/50*2*pi;x=sin(t);y=cos(t);Hr=@cirline;feval(Hr,flag,x,y,t)%------subfunction-----------function cirline(wd,x,y,t)switch wd case 'line' plot(t,x,'b',t,y,'r'); case 'circle' plot(x,y,'-g') otherwise error(' 输入宗量错 !')endaxis square

% 主调函数exm060301('line')HH=exm060301('circle') %绘图并返回子函数句柄t=(0:2*pi/5:2*pi);x=cos(t);y=sin(t);HH('circle',x,y,t) % 通过子函数句柄直接调用子函数

Page 34: 第六章   M 文件和函数句柄

匿名函数提供了一种创建简单程序的方法,使用它用户可以不必每次都编写 M 文件。用户可以在 MATLAB 的命令窗口或是其他任意 M 文件和脚本文件中使用匿名函数。

匿名函数的创建格式为: FH = @(arglist) expr

其中 FH 是为该函数创建的函数句柄;@ 符号用于创建函数句柄; arglist 为用逗号分隔的参数列表; expr 为函数主体,为 MATLAB 表达式。

匿名函数的调用格式为: FH (arglist) %直接调用

feval(FH, arglist) %间接调用

6.3.3 匿名函数

Page 35: 第六章   M 文件和函数句柄

嵌套函数

• 一个函数内部可以定义其他的函数,这种内部的函数称作嵌套函数。

• 1.嵌套函数的书写• 定义嵌套函数时,只要在一个函数内部直接定义嵌套函数即可。需要注意的是当一个 M 文件中存在嵌套函数时,该文件内的所有函数必须以 end 结尾。

Page 36: 第六章   M 文件和函数句柄

私用函数的构造与普通 M 函数完全相同;私用函数只能被 private目录的直接父目录上的 M

函数文件所调用。它不能被其他目录上的任何M 函数、M脚本文件或 Matlab 指令窗中的命令所调用,也不能被直接父目录上的 M脚本文件调用。

M 文件中,任何指令通过“名字”对函数进行调用时,私用函数的优先级虽低于内装函数和子函数,但高于其他任何目录上的函数

help, lookfor 等指令都不能提供关于私用函数的任何帮助信息。

私用函数

Page 37: 第六章   M 文件和函数句柄

串演算函数

• 一种是串演算函数 eval ,它具有对字符串表达式进行计算的能力;

• 另一种是“函数句柄演算函数” feval ,它具有对函数句柄进行操作的能力。

Page 38: 第六章   M 文件和函数句柄

y=eval('CEM') 执行 CEM 指定的计算[y1,y2,…]=eval('CEM') 执行 CEM 代表的函数文件,并输出结果

• eval 指令的输入参量必须是字符串;• 构成字符串 CEM ,可以是 Matlab 任何合

法的指令、表达式、语句或 M 文件名;• 第二种格式中的 CEM只能是(包含输入参

量在内的)M 函数文件名;

Page 39: 第六章   M 文件和函数句柄

6.4 函数句柄

函数句柄是 matlab 的一种数据类型,携带着“相应函数创建句柄时的路径、视野 (Scope) 、函数名及重载方法”。

优点 :

使函数调用像变量一样灵活方便拓宽子函数包括局部函数的使用范围提高函数调用的可靠性和软件的重用性减少程序设计中的冗余提高重复执行的效率

6.4.1 函数句柄的创建和观察

Page 40: 第六章   M 文件和函数句柄

函数句柄的定义有两种:( 1)在提示符 @ 后添加相应函数的函数名;( 2)利用转换函数 str2func。

f_h=@plot %与 f_h=str2func('plot')等价 则 : f_h = @plot 函数句柄内涵的观察通过 functions实现 functions(f_h)ans = function: 'plot' type: 'simple‘ file: 'MATLAB built-in function‘

6.4.1 函数句柄的创建和观察

Page 41: 第六章   M 文件和函数句柄

6.4.2 函数句柄的基本用法如果一个函数的调用格式为:[argout1,argout2,…argoutn]=FunName(argin1,argin2,…,arginn)

假设该函数的句柄为 ,那么通过函数句柄实现函数运算的调用格式为 :

(1) 直接调用格式[argout1,argout2,…,argoutn]=hfun(argin1,argin2,..,arginn)

(2) 间接调用格式[argout1,argout2,…,argoutn]=feval(hfun,argin1,argin2,..,arginn)

Page 42: 第六章   M 文件和函数句柄

6.4.2 函数句柄的调用 (1) 直接调用 例 : f_h1=@peaks %f_h1=str2func(‘peaks’)

f_h1(50)

(2) 间接调用 : feval( 函数句柄,参数列表)

例 : f_h=@plot %f_h=str2func(‘plot’)

feval(f_h,0:10,0:10)

Page 43: 第六章   M 文件和函数句柄

例 6.2-1 :根据指定不同的半径、色彩、线型,绘出圆周线或圆。

function [S,L]=exm060201(N,R,str)switch nargin case 0, N=100;R=1;str='-b'; case 1, R=1;str='-b'; case 2, str='-b'; case 3 ; otherwise, error(' 输入量太多 ');end;t=0:2*pi/N:2*pi;x=R*sin(t);y=R*cos(t);if nargout==0,plot(x,y,str)elseif nargout>2,error(' 输出量太多 ');else S=N*R*R*sin(2*pi/N/2); L=2*N*R*sin(pi/N); fill(x,y,str)endaxis equal square,box on,shg % 将该函数 M 文件存于

c:\

调用:[S,L]=exm060201(8,2,'-

g')[S,L]=exm060201(7,3)[S,L]=exm060201(5)[S,L]=exm060201exm060201(8,2,'-g')

函数句柄调用:H=@exm060201[S,L]=H(7,3)改变路径为 d:\ 再调用:[S,L]=H(5,2)exm060201(8,2,‘-g’)

Page 44: 第六章   M 文件和函数句柄

 域名          说  明function        句柄所代表的函数名

type

函数类型

simple 无重载的内建函数 ,M,P 函数文件或无法判断类型的函数

subfunction 子函数private 私用函数constructor matlab类的对象构造函数overloaded 有重载的函数

file 非重载数据类型所对应的源代码及路径,若有内建函数,总列在此栏

methods 仅当函数类型为重载时,返回结构才有该域

Page 45: 第六章   M 文件和函数句柄

小 结

• matlab 的程序结构 : 顺序、分支、循环结构

• 程序 M 文件 , 函数 M 文件 , 函数文件一般结构

• 函数类别,主、子函数,匿名函数• 函数句柄 : @plot, str2func(‘plot’)

Page 46: 第六章   M 文件和函数句柄

习题 5 (Page226) 1,4,5,7 题