第2章程序设计.docx
《第2章程序设计.docx》由会员分享,可在线阅读,更多相关《第2章程序设计.docx(19页珍藏版)》请在冰豆网上搜索。
![第2章程序设计.docx](https://file1.bdocx.com/fileroot1/2023-2/3/d3470eb3-7e7f-4a30-8711-af5cee430cf8/d3470eb3-7e7f-4a30-8711-af5cee430cf81.gif)
第2章程序设计
第2章程序设计
虽然Matlab中提供了大量的函数及工具箱可供使用,在实际应用中,仍然经常需要自己编写Matlab程序或函数,以完成特定的功能。
作为一种开发工具,Matlab提供了完整的条件判断和各种控制流语句,可以进行非常复杂的程序设计工作。
2.1逻辑运算
2.1.1关系运算符
关系运算符主要用于比较两个对象之间是否满足某种关系,若满足则比较结果为真,返回数值1,若不满足则返回结果为假,返回数值0。
Matlab的关系运算操作符:
关系操作符
关系操作函数
意义
说明
C=(A==B)
C=eq(A,B)
判断A与B是否相等
A,B可以是标量,矩阵,或者其它对象,如figure,string等对象。
其中C由0和1组成,且与A,B中某个是同型的(即可能是标量,向量或矩阵)
C=(A~=B)
C=ne(A,B)
判断A与B是否不相等
C=(A
C=lt(A,B)
判断A是否小于B
C=(A>B)
C=gt(A,B)
判断A是否大于B
C=(A<=B)
C=le(A,B)
判断A是否小于等于B
C=(A>=B)
C=ge(A,B)
判断A是否大于等于B
示例:
A=[12;34];
B=[10;01];
C1=A==B
C1=
10
00
C2=le(A,B)
C2=
10
00
2.1.2逻辑运算及逻辑函数
逻辑运算及逻辑函数在计算机语言中是普遍存在的,它对于程序的执行次序起着重要的作用。
Matlab中的逻辑运算符及函数:
逻辑操作
逻辑“与”
逻辑“或”
逻辑“非”
逻辑“异或”
逻辑运算符
C=A&B
C=A|B
C=~A
逻辑函数
C=and(A,B)
C=or(A,B)
C=not(A)
C=xor(A,B)
说明
当A,B同为真时,C为真;否则C为假。
当A,B中至少有一个为真,则C为真;否则C为假。
若A为真,则C为假;否则C为真。
当A,B中只有一个为真,则C为真;否则C为假。
结果
A,B均为逻辑变量(标量,向量或矩阵(须同维)均可),当然C也是逻辑变量,且与A或B中一个同维。
优先级
“非”>“与”>“或”(注:
“异或”为一函数形式的运算)
运算次序
在同一括号内,运算从左到右。
可通过增加括号改变运算次序
函数logical
在较低的版本中,C=[0110]可表示为一逻辑数组(由0,1组成),这在高版本中给予加强,需用C=logical([0110])表示。
示例:
A=[12;34];
B=ones
(2);
C1=and(A,B)
C1=
11
11
C2=(A|B)&(not(A))
C2=
00
00
xor(A,B)
ans=
00
00
2.1.3逻辑关系函数运算
我们给出三个常用的逻辑关系函数运算,其余的对大多数用户来说,是用不到的,因此在这里不再冗述。
函数名
使用说明
any
若向量或矩阵的每一列中有非零元素,则返回真,否则为假
all
若向量或矩阵的每一列中所有元素非零,则返回真,否则为假
find
寻找非零元素位置
示例:
A=[12;01];
any(A)
ans=
11
all(A)
ans=
01
find(A)
ans=
1
3
4
all(any(A))%判断矩阵A的每一列是否都有非零元素
ans=
1
2.2Matlab的循环控制
Matlab提供的控制流程的几个命令与C语言很相似,对于学过C语言的用户来说,掌握它并不困难。
2.2.1无条件循环
当需要无条件重复执行某些命令时,可以使用for循环。
for循环的使用形式为:
forvar=array
{commands}
end
说明:
·for:
循环开始的关键字;
·var:
循环控制变量;
·array:
循环控制向量(不一定是单调的!
)。
执行第i次时,循环变量var就取循环控制向量中的第i个值,即var=array(i);取到第n个值时,循环结束。
·{commands}:
要重复执行的命令行(可有多行命令或者没有命令)。
·循环语句中的“;”可防止中间结果的输出。
·end:
循环结束的关键字(要和for成对使用)。
需要注意的一点是,在{commands}中给变量var赋某些值,如var=array(n),并不改变循环的进程,还是循环n次后才结束。
且for循环可以根据需要嵌套多次。
例2-1设有向量t=[-10135]’,由此产生一个5×5的Vandermonde(范德蒙)矩阵。
解:
程序如下:
t=[-10135]';
n=max(size(t));
forj=1:
n
fori=1:
n
A(i,j)=t(i)^(j-1);
end
end
A
A=
1-11-11
10000
11111
1392781
1525125625
以上为双循环语句。
若编写为带有向量运算的单循环语句就要快得多,程序如下:
t=[-10135]';
n=max(size(t));
A(:
1)=ones(n,1);
forj=1:
n-1
A(:
j+1)=t.*A(:
j);
end
A=
1-11-11
10000
11111
1392781
1525125625
2.2.2条件循环
当只有满足某些条件时,才重复执行某些命令,这时需要条件循环控制。
Matlab提供了两个条件循环控制语句。
2.2.2.1if-else-then语句
if-else-then语句常使用的三种形式为:
ifexpression
{commands}
end
ifexpression_1
{commands_1}
else
{commands_2}
end
ifexpression_1
{commands_1}
elseifexpression_2
{commands_2}
elseifexpression_3
{commands_3}
…
else
{commands_n}
end
说明:
·expression,expression_i:
Matlab表达式,它的结果是个数值(零或者非零),用于控制执行方向;
·else,elseif:
表达式expression或者expression_i的另外一些情形;(可有可无,根据实际情形而定。
)
·commands,commands_i:
需要重复执行的语句组。
当其前面的表达式为真(非零)时,就执行该语句组。
示例:
n=input('输入数值n:
')%用户输入提示命令
ifrem(n,2)~=0%求n/2的余数
M=magic(n)%魔方矩阵
elseifrem(n,4)~=0
M=sqrt(n)
else
M=sin(n)
end
运行结果为:
输入数值n:
3
n=
3
M=
816
357
492
输入数值n:
6
n=
6
M=
2.4495
输入数值n:
12
n=
12
M=
-0.5366
2.2.2.2while循环语句
while循环语句的一般使用形式为:
whileexpression
{commands}
end
说明:
·expression:
循环控制表达式,其值为一个数值(零或者非零);
·{commands}:
需要重复执行的语句组,当其前面的表达式为真(非零)时,就执行该语句组。
示例:
n=1;
whileprod(1:
n)<1.e100%prod为求元素之积
n=n+1;
end
>>n
n=
70
2.2.3分支结构
有些时候,需要对不同的情形执行不同的操作。
Matlab提供了switch分支语句。
其常使用的格式为:
switchexpression
case_1
{commands_1}
case_2
{commands_2}
…
otherwise
{commands_n}
end
说明:
·expression:
Matlab表达式,其值为一个Matlab数据类型(标量、矩阵、字符串等),用于控制选择执行方向;
·case_i:
第i种情形表达式;
·otherwise:
除掉以上所有的case_i之外的情形;
·commands_i:
当expression之值为case_i时,就执行该语句组。
示例:
n=input('n:
')
switch(rem(n,4)==0)+(rem(n,2)==0)
case0
M=magic(n)
case1
M=ones(n)
case2
M=zeros(n)
otherwise
error('Thisisimpossible!
')
end
n:
3
n=
3
M=
816
357
492
n:
6
n=
6
M=
111111
111111
111111
111111
111111
111111
n=
12
M=
000000000000
000000000000
000000000000
000000000000
000000000000
000000000000
000000000000
000000000000
000000000000
000000000000
000000000000
000000000000
2.2.4break命令
break语句通常用于循环语句,有时当满足一定条件时就要跳出循环,执行其它操作。
这一般是用if语句来进行条件判断,若满足就调用break语句来跳出。
Break语句只能跳出包含它本身的循环体。
例如,下面的程序是利用二分法计算一多项式的一个根。
a=0;fa=-inf;b=3;fb=inf;
whileb-a>eps*b
x=(a+b)/2;
fx=x^3-2*x-5;
iffx==0break
elseifsign(fx)==sign(fa)
a=x;fa=fx;
else
b=x;fb=fx;
end
end
x
x=
2.0946
例2-2求鸡兔同笼问题,鸡兔同笼,头共36,脚共100,求鸡、兔各多少?
解:
i=1;
while1
ifrem(100-i*2,4)==0&(i+(100-i*2)/4)==36
break;
end
i=i+1;
end
a1=i
a2=(100-2*i)/4
a1=
22
a2=
14
2.2.5return语句
该语句使函数正常结束并返回调用它的函数继续执行,或返回Matlab命令窗口。
例如,在下面的函数中,当矩阵A为空矩阵时,马上返回命令窗口。
functiond=det(A)
ifisempty(A)
d=0;
return
else
{其它语句…}
end
2.3M—文件
2.3.1脚本文件
对于简单问题,在Matlab的提示符下直接输入命令是快速有效的。
然而当命令数量增加或希望改变一个或几个变量的值或某个命令需要重复多次时,直接输入就非常麻烦。
像DOS一样,把许多可执行的命令放到后缀为方便用户.bat的批处理文件中,只要在DOS提示符下输入批处理文件的文件名,即可执行多个命令。
与此类似,可把许多可执行的Matlab命令放在后缀为.m的文件中,只要在Matlab的提示符下输入m-文件的文件名(不用跟上后缀.m!
),即可执行多个命令。
这个后缀为.m的文件,称之为脚本文件(ScriptFile)。
示例:
将上例作为脚本文件的一个简单例子,在M-edit窗口编写以下内容:
%jitu.m
i=1;
while1
ifrem(100-i*2,4)==0&(i+(100-i*2)/4)==36
break;
end
i=i+1;
end
a1=i
a2=(100-2*i)/4
输入完成后,以文件名为jitu.m存盘(注意加上后缀!
)。
在Matlab命令窗口的提示符下输入:
jitu(回车)
a1=
22
a2=
14
2.3.2函数文件
在前面使用的许多函数中,如abs(x),sqrt(x),Matlab获取传递给它的变量,利用所给的输入,按要求计算出结果,然后返回结果给Matlab。
至于函数执行了什么操作以及产生的中间结果都是隐含的,我们看到的仅是输入参量与输出的结果。
Matlab虽然有众多的函数,但仍不能包含所有用户某些特殊用途的“特殊”函数。
所以Matlab提供了一个用于创建用户函数的命令function,用以扩充Matlab的函数功能。
例2-3计算第n个Fibonacci数。
解:
打开M-edit窗口,编写如下程序:
functionf=fibfun(n)
%FIBFUNForcalculatingFibonaccinumbers.
%Incidengtally,thenameFibonaccicomesfrom
%FiliusBonassi,or"sonofBonassus"
%fibfun.m
ifn>2
f=fibfun(n-1)+fibfun(n-2);
else
f=1;
end
编写完毕,以“fibfun.m”为文件名存盘。
然后在Matlab命令窗口中执行如下命令:
fibfun(17)
ans=
1597
一个函数文件和一个脚本文件类似之处在于它们都有一个.m为后缀的文本文件(ASCII码文件);都不能在命令窗口编辑,只能在文本编辑器中进行编辑。
不同之处在于两者的通讯方面。
函数文件有自己的规则和属性:
1.文件名必须与函数名相同。
如三角函数sin必须存在名为sin.m的文件中。
即函数的调用是以文件形式进行的:
找到该文件,再对它其中的命令进行计算,最后给出最终的计算结果;
2.对于一个刚执行过的函数文件,Matlab把它编译成存储器的内部表示,以加速以后所有的调用。
若函数中有对其它函数的调用,它同样也被编译到存储器内。
对于一般的脚本文件,Matlab没有对它进行编译,而是逐行解释(不管以后是否再执行),只有使用频繁的脚本文件,如:
dir,who(s),lookfor等内部命令,才是已经编译到存储器中,以加快调用速度;
3.函数文件以关键字function打头,以下是[输出参量]=函数名(输入参量),其中输出参量与输入参量都可以有多个(用逗号分隔)或者没有,若只有一个输出参量,则方括号可以省略,且这些参量都是形式参量;
4.函数可以按少于函数文件中所规定的输入参量和输出参量个数进行调用,但不能多于所规定的输入和输出参量的数目,否则调用会给出出错信息;
5.当调用一个函数时,各个参量的位置是规定好的,所以要注意调用时实参的顺序;
6.第一行为帮助行,是由命令lookfor搜索的行;
7.在M-文件中,到第一个非注释行为止的注释行都是帮助文本。
例如:
>>helpfibfun,则返回第1行~第4行的文本;
8.函数有它们自己的工作空间,与Matlab的工作空间是分开的。
两个空间的唯一联系是函数的输入和输出参量。
若函数中某个输入参量发生变化,仅影响函数工作空间。
函数空间中产生的中间变量,只是在函数执行期间中存在,过后就消失(所以在调试中有命令dbup,dbdown,进行空间转移);
9.若某个变量定义成全局变量,则该函数可以与其它函数、Matlab的工作空间和递归调用本身共享变量。
这时用到命令global来定义全局变量。
为了避免与其它变量混淆,建议全局变量使用大写字母;
10.函数文件中可以包含脚本文件,但这时脚本文件查看的是函数工作空间,而非Matlab工作空间。
函数在执行过程中遇到脚本文件,还是逐行解释,故在函数文件中调用脚本文件降低执行速度;
11.函数可以递归调用,即函数可以调用自己。
这在许多场合是有用的。
要注意一点是避免陷入死循环;
12.当函数文件执行到终点,或者是遇到返回命令return,就停止执行并返回;
13.在函数文件执行过程中,若遇到非法操作,命令error可在命令窗口中显示一个出错字符串,终止执行,把控制权交给键盘。
14.在(母)函数中可以包含(多个)子函数,即子函数是只有该函数调用的具有某些小功能的函数。
子函数的书写形式与(母)函数相同。
2.4Matlab的注释和标点
1.在计算过程中,当有些中间变量(或不重要的变量)的值我们不想显示时,就在命令后面加分号(“;”)来禁止显示;
2.多条命令可以写在同一行,只需要用逗号和分号将它们隔开;
3.有时某些命令或者数据在一行不能全部显示,或者是为了形式上的美观,我们可以在必要的地方加上续行符(“…”),当然一个数字或者字符串(变量名或者函数名等)不能断成两行;
4.有时在我们编写的程序中,需要加上某些注释或者文档(一般是便于阅读程序),这时需在文档前面加上注释符(%)即可。
注意一点的是,新的注释行前不能用续行符,只能用注释符;
5.在定义单元数据(一种数据类型)时,用到“{}”给某个单元赋值,“{}”在赋值语句(“=”)的左边或者右边出现均可;
6.在单元数据结构中,如果要对变量下面的域名进行操作,需用到域间隔符号(“.”),如:
student.Name。
说明:
在PC机上,用户可以用Ctrl+C组合键来中断正在运行的函数(当计算时间较长或者死循环时可用)。
2.5M-文件的出错信息与调试
运行一个文件,当不能正常运行通过时,Matlab会给出错误信息。
根据所给信息,利用Matlab的运行调试器(DEBUGGER),逐步改正错误,直到运行能通过为止。
情形1:
命令:
(回车)
出错信息:
?
?
?
Undefinedfunctionorvariable‘’.
或者为:
?
?
?
UndefinedvariableorcapitalizedinternalfunctionDIR;CapsLockmaybeon.
可能原因:
·m-文件名输入错误或者根本不存在该文件;
·m-文件不在搜索路径上;
·m-文件名中出现大写字母。
改正对策:
·确认m-文件名的正确输入或者是建立该文件;
·把该文件拷贝到Matlab的当前工作目录上或者是搜索路径上;或者是增加该文件所在的目录到搜索路径上;或者把当前工作目录转成该文件所在的路径;
·文件全部改成小写字母。
情形2:
命令:
operator
出错信息:
?
?
?
operator.
|
Missingoperator,comma,orsemi-colon.
可能原因:
·作变量(字符串)运算,用错(漏)了操作符,Matlab认为缺少了操作符;
·运行某一文件,但跟上了后缀(.m),Matlab认为作的是变量运算。
改正对策:
·确认正确使用操作符(包括点运算);
·把文件名的后缀去掉即可。
当然程序运行出错的原因是多种多样的,在此,我们不能把所有的出错信息罗列出来。
不过,结合Matlab提供的调试工具“Debug”找错,可以逐步找出问题所在。
当一个函数在调用过程中出错或者是得到错误的结果时,在排除算法有误的条件下,应对该函数进行调试,找出错误。
·结合错误信息,在函数中可能出错的语句前设定断点(把光标置于该行),再点击SetBreakpoint按钮([按钮图标]),可又设置多个断点;
·在命令窗口中做些“准备”工作。
如:
定义符号变量,给函数的输入参量赋初值,以供函数在调试过程中使用。
在命令窗口中调用该函数;
·在Matlab运行到函数的断点处,会在命令窗口中显示字母K,同时把控制权交给键盘。
这时用户可以检查一些变量的值或者其它操作;
·由于一个函数中的语句的执行要调用其它函数,一般是调用其它函数计算时出错,从而我们可以找出错误所在,改正程序错误之处。
Matlab的调试函数
调试命令
(命令窗口)
调试按钮
(调试器)
调试功能
dbstop
设置断点
dbclear
清除断点
dbcont
在断点处继续执行下面的操作
dbdown
工作空间下移
dbup
工作空间上移
dbstep
执行断点后的一行或者多行语句
dbquit
退出调试模式
dbtype
列出带行号的M原文件
dbstack
Stack:
列出该函数调用的堆栈
dbstatus
列出所用断点