You are on page 1of 76

Matlab 提供内部函数以及工具箱,都是利用 Matlab 语言开发 M 文件

常用两种工作方式: 交互式命令行操作方式 M 文件编程工作方


第三章 MATLAB 程序设计


参考《 MATLAB 基
3.1 M 文件建立 础及其应用教程》—
— 第六章

3.2 脚本(命令)文件 MATLAB 程序设计


《 21 世纪全国应用
型本科电子通信系列
3.3 函数文件 实用规划教材》

3.4 程序控制结构 化科学计算》 高等院


参考《 MATLAB 可视

校计算机技术“十二
3.5 程序调试 五”规划教材

用户也可以结合自己的工作需要,开发自己的函数程序或工具箱
3.1 M 文件建立
1. M 文件 Matlab 语言编写的程

① Matlab 命令和函数组合构成,可完成某操作和算法

② 存储文本文件,扩展名为 .m 的 M 文
件;
③ 文本编辑器: M 文件编辑器
windows 的记事本
word 文件
④ M 文 件 分 Script 脚本文 Function 函数文
件 件
类:
2.M 文件建立和打开 M 文件编辑器

(1) 新建 M 文件 ( 2 )打开 M 文件

 命令操作 : edit edit M 文件名

 命令按钮 : 快捷键

 菜单操作 : 新建 打开
3 . M 文件保存和搜索路径
M 文件应保存在搜索路
显示 M 文件路径:which filename
径或当前目录,才能在
命令窗口调用运行
设定当前目录: cd d:\myfile

设定搜索路径:>> addpath(' folder path')


addpath folder path set path  (add folder)

删除 rmpath(' folder
path')
4. 显示 M 文件内容
调用格式: type M 文件 命令窗口显示

>> which rsp


aaaa not found.
>> cd c:\Users\Desktop\matlab
>> addpath(‘C:\Users\Desktop\matlab’)
>>edit rsp
>>type rsp type rsp.m
r=22
s=pi*r*r
p=2*pi*r
通常执行简单 matlab 命
3.2 脚本 ( 命令 ) 文件 令

1. 编写脚本文件格式 求半径为 r 的圆的面积和周长

% FCIRCLE calculate the area and perimeter of a circle for radii r


H1 注释行
 % 开头注释行,大写体文件名和运用关键词简要描述函数功
% r 圆半径
能;
% s 圆面积  在线帮助使用; lookfor 只 H1 行查询关键词。
 H1 行后面 % 的注释行组成;
% p 圆周长 帮助文本区
 详细说明函数功能脚本文件变量等说明
% 2017 年编  Help name 显示所有的 % 的注释行。

r=22; % 半径,程序中赋值
s=pi*r*r ; % 计算圆面积 s文件主体  实现脚本文件功能的指令组成;

p=2*pi*r ; % 计算圆周长 p 注释行


保存文件名: fcir
cle 在当
保存名不要和计算 前目录和搜索路径
机命令、函数、文
单击 F5 键存储并运行 M 文 件名相同
2. 调用脚本文件
% 调用保存脚本文件名
>>filename
>> s 编程时中间结果无需显示,
>> fcircle s = 1.5205e+03
>> p 命令行末加‘;’ ,
p = 138.2301 调试时需要显示中间结果,
>> whos 则不必加分号。
Name Size Bytes Class Attributes
p 1x1 8 double
r 1x1 8 double
s 1x1 8 double

 运行后所有变量驻留在基本工作空间( base
workspace )
3. 数据输入
① 编程中直接赋值给输入变量值
clear >> rsp % 调用程序结果
r=33 % 程序中赋值输入变量 s = 3.4212e+003
s=pi*r*r 保存 p = 207.3451
p=2*pi*r rsp

② 程序运行中从键盘敲数据给输入变量

Input 在程序运行中从键盘输入数据给变量
r=input('r=') % 从键盘赋值输入变 >> rspi % 调用程序结果
量 r=33
s=pi*r*r 保存 rspi s = 3.4212e+003
p=2*pi*r p = 207.3451
此程序编写只针对一个标量运算,所以运算符无
所谓矩阵运算符还是数组运算符
保存 rspi
r=input(‘r=’);
r=input('r=');
s=pi*r.*r ; % 数组运算
s=pi*r*r ; 修改为
p=2*pi*r;
p=2*pi*r;
批量重复运算应为是数组运算
>> rspis % 调用程序
结果
>> rspi % 调用程序结果
r=1:2:6;
r=33
>> p
s = 3.4212e+003
p = 6.2832 18.8496
p = 207.3451
31.4159
数值运算大部分为数组运算 >> s
s = 3.1416 28.2743
78.5398
数据输入格式 从键盘给变量 A 输入数据

① 输入数值变量 A=input(‘ 提示信


息’ )
A=input('Please input A: ')
Please input A:33 A=33

② 输入字符串变量 A=input(‘ 提示信息’ ,'s' )

name=input('What''s your name? ', 's')


What's your name? lili name =lili

输入 1+4 分别为数值变量和字符串变量
① 输入数值变量 ② 输入字符串变量
>> a=input('input >> b=input('input
example:') example:', 's' )
input example:1/2 input example:1/2
a= b=
0.5000 '1/2'
>> whos
Name Size Bytes Class Attributes
a 1x1 8 double
b 1x3 6 char
4. 命令窗口输出函数 disp
数据 A 输出: >> x=1:2:5; % 分
号不显示结果
① 数值变量 disp(A
) >> disp(x)
x = 1 3 5
② 字符串变量 disp(‘A’)
disp('the x value is:');
disp(x); the x value is: 1 3 5
③ 数值转换字符串 num2str(x)
>> disp(['the x value is:', num2str(x)])
the x value is:1 3 5
编脚本文件求半径为 r 的圆的面积和周长,数据输出用
disp

①无数据输出函数 ②数据输出结果显示在命令窗口
保存 rspi r=input('r=');
clear s=pi*r.*r; 保存 rspid
r=input('r='); p=2*pi*r;
s=pi*r.*r; disp(['s=',num2str(s),',p=',
p=2*pi*r; num2str(p)])

编程命令行末加‘;’, 运行结果:
结果不显示在命令窗, >> rspid
但存在内存空间 r=22
s=1520.5308,p=138.2301
5. 命令窗口格式化数据输出 fprintf
将变量 A 按指定格式 format 输到命令窗口显

fprintf( format, 程序 rspif:
r=input('r=');
A) : 指定数据输出格式 , 必须有 %
format s=pi*r.*r;
%d 整数 p=2*pi*r;
%e 实数:科学计算法形式 fprintf('%e',s);
%f 实数:小数形式
%g 由系统自动选取上述两种格式之一 fprintf('%f',s);
%s 输出字符串 运行结果:
A :要输出的数据变量 >>rspif
r=22
1.520531e+03

例 创建一个字符矩阵并存入磁盘,
再读出赋值给另一个矩阵。
>> a='string';
>> fid=fopen('d:\char1.txt','w');
>> fprintf(fid,'%s',a);
>> fclose(fid);
>> fid1=fopen('d:\char1.txt','rt');
>> b=fscanf(fid1,'%s')
6. 脚本文件特点
① 一串命令行简单叠加的集合;
② 自动按顺序执行文件的命令;
特征向量 v 和特征
③ 不需要输入和输出量; 值 d [v,d]=eig(a)
④ 变量一旦生成,一直保留 workspace 工
作空间中(内存空间),除非 clear 和退
出;
⑤ 所有变量均为全局变量。
3.3 函数文件格式
求半径为 r 的圆的面积和周长
例 编写函数文件格式
function [s,p]=fcircle(r) 函数定义行
% FCIRCLE calculate the area and perimeter of a circle of radii r
H1 注释行 调用、运行、工作
%r 圆半径 空间、变量及存储截然
不同于脚本文件
%s 圆面积
帮助文本区
%p 圆周长
% 2017 年 7 月 30 日编 函数文件 fcircle
s=pi*r.*r; % 计算圆面积 s
函数体
p=2*pi*r; % 计算圆周长 p 脚本文件 fcircle
end
常用开发应用程序
3.3 函数文件 和扩充 MATLAB 函
数库

3.3.1 函数文件

3.3.2 全局变量和局部变量

3.3.3 子函数与主函数

3.3.4 函数句柄和匿名函数
Matlab 提供内部函数以及各种工具箱,都是利用 Matlab 语言开发的 M 函
数文件
3.3.1 编写函数文件
1. function 定义行
function 输出形参数 = 函数名 ( 输入形参
数)
 第一行 function 引导词,表示是函数文件 ;

 函数名的命名要有含义,规则和变量名相同; roots , inverse

 保存 M 文件名要同函数名同名,即 M 文件名为函数名 .m ,方便调


用,

如不同 , 调用函数时用 M 文件名; [v,d]=eig(a)

 列出函数与外界联系的全部输入 / 输出形参数;

 输出多个参数应写作行向量,用方括号 [v1,v2] ;
 输入 / 输出量可有可

① 全部输入输出量 另存
function [s,p]=fcircle (r) fcirlce
s=pi*r.*r; 运行结果
p=2*pi*r; >> [s,p]=fcircle(22)
s = 1.5205e+03
end p = 138.2301

② 少部分输出量
function p=fcircle1(r)
s=pi*r.*r; 另存 fcirlce1
p=2*pi*r;
运行结果
end >> pp=fcircle1(22)
pp = 138.2301
输出量可有可无
function ex_18(a,b)
x=a:0.1:b; 1.45

y1=sin(x); 1.4

y2=cos(x); 1.35

y=y1-y2; 1.3

plot(x,y) 1.25

end 1.2

1.15

1.1
2 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3
2. 函数调用
① 调用格式:[ 输出实参数 ]= 函数名 ( 输入实参
数)
编写函数 function [s,p]=fcircle(r)

输出形参数 function [s,p]=fcircle (r)


输入形参数 s=pi*r.*r;
p=2*pi*r;
end
调用函数 >> [s,p]=fcircle(22)
输出实参数 s =1.5205e+03
输入实参数 p =138.2301

函数调用时实参数名与函数定义时形参数名可以一致
函数调用时,先将实参传递给相应的形参,从而实现参数传递,然后再执行函数的功
能。
② 函数调用特点
I. 函数调用时实参数名可以与函数定义时形参数名一致,也可以不一致

function [s,p]=fcircle (r) >> rr=234; 函数调用实参


s=pi*r.*r; % 计算圆面积 s 数
>> [x,y]=fcircle(rr)
p=2*pi*r; % 计算圆周长 p x =1.5205e+03 % x 圆面积
end 函数定义形参数 y =138.2301 % y 圆周长

II. 函数调用时实参数顺序应与函数定义时形参数顺序一致, 否则出错


>> [p,s]=fcircle(22)
p = 1.5205e+03 % p 计算圆面积
s = 138.2301 % s 计算圆周长
III.调用输入 / 输出量数目可少于函数定义中规定的数目。
>> p=fcircle(22)
p = 1.5205e+03
IV. 运行后只保留最后结果在内存空间 workspace ,不保留中间过
程; 迭代法求解线性方程的 MATLAB 函数文件
Jacobi
函数调
function [x,n]=jacobi(A,b,x0,eps)
例 if nargin==3

>> [xx,nn]=jacobi([10,-1,0;-
eps=1.0e-6; % 迭代精度 1,10,-2;0,-2,10],[9,7,6]',
elseif nargin<3 [0;0;0])
error xx =
return 0.9958
end 0.9579
D=diag(diag(A)); % 求 A 的对角矩阵 0.7916
L=-tril(A,-1); % 求 A 的下三角阵 nn =
U=-triu(A,1); % 求 A 的上三角阵 11
B=D\(L+U);
f=D\b;
x=B*x0+f; % 迭代解
n=1; % 迭代次数
while norm(x-x0)>=eps
x0=x;
x=B*x0+f;保留最后实参数结果 xx 和 nn ;
n=n+1;
形参数、对角矩阵 D, 下三角阵 L, 上三角阵 U 中间结果没有
end
IV. 开辟临时函数工作空间 (Function workspace) 存放中间变量,并运行 ;
例 V. 运行完毕,中间变量和形参数被清除以及临时空间关闭;
VI. 函数参数为局部变量
(1) 为显示中间结果,取消中间参数分号

function [x,n]=jacw(A,b,x0,eps) ( 2 )调用函数文件 jacw


if nargin==3 [xx,nn]=jacw([10,-1,0;-1,10,-2;0,-
eps=1.0e-6; % 迭代精度 2,10],[9,7,6]',[0;0;0])
elseif nargin<3 D =10 0 0
函数定义形参数 调用文件时,去除中间参
error 0 10 0
数后分号,将在命令窗口
return 0 0 10 显示中间参数 D,L , x 结
end L = 0 0 0 果;
D=diag(diag(A)) % 求 A 的对角矩阵 1 0 0 但在基本工作空间
L=-tril(A,-1) % 求 A 的下三角阵 0 2 0 workspace 只有保留最后
U=-triu(A,1) % 求 A 的上三角阵 U=0 1 0 结果 xx 和 nn ;无对角矩
B=D\(L+U) 0 0 2 阵 D, 下三角阵 L, 上三角
0 0 0 阵 U , x 的中间结果
f=D\b
x=B*x0+f; % x 迭代解 x = 0.9000 % 函数定义 x 迭代解
n=1; % 迭代次数 0.7000
while norm(x-x0)>=eps 0.6000
x0=x;
通常,每个函数体内部有自己定义的变量,不能从其他函数和 xx = 0.9958 % 函数调用 xx 迭代解
MATLAB 工
x=B*x0+f; 0.9579
作空间访问这些变量,这些变量即是局部变量。
n=n+1; 0.7916
end 函数使用时就是一个黑箱,有数据输入,经加工,输出结果 nn = 11
③ 确定输入和输出参数的数目
分别记录调用该函数时的输入实参数和输出实参数的个数

输入个数 nargin(‘ 函数
名’ )
输出个数 nargout(‘ 函数
名’ )r = roots(c)
nargin('roots')
ans = 1

nargout('roots')
输入个数不确定
ans = 1
显示负值
nargin(‘plot') ans = -1
function [x,n]=jacobi(A,b,x0,eps)
if nargin= =3
eps=1.0e-6; % 迭代精度 >> nargin('jacobi')
例 elseif nargin<3 ans = 4
error >> nargout('jacobi')
return
ans = 2
end
Jacobi D=diag(diag(A)); % 求系数矩阵 A 的对角矩阵
L=-tril(A,-1); % 求 A 的下三角阵
迭代法
U=-triu(A,1); % 求 A 的上三角阵
求解线 B=D\(L+U);
性方程 f=D\b; %b 常数列向量
x=B*x0+f; % 迭代解 运行结果
的函数
n=1; % 迭代次数 >> A=[10,-1,0;-1,10,-2;0,-2,10];
文件 : b=[9,7,6]';
while norm(x-x0)>=eps [X,n]=jacobi(A,b,[0,0,0]',1.0e-6)
x0=x; X =0.9958
x=B*x0+f; 0.9579
n=n+1; % 迭代次数 0.7916
end n = 11
④ 脚本文件和函数文件的区别
脚本式 M 文件 函数式 M 文件
无函数定义行; 有函数定义行;
无输入和输出量 可有输入和输出变量
在 base workspace 中数据操作,中间变量存在临时工作空间,
运行后变量驻留其中; 它随函数结束而删除;
全局变量。 局部变量,除特别声明。
3.3.2. 全局变量和局部变量
1. 全局变量:
① 所有变量驻留在基本工作空间中,即全程有效;

② 所有函数都可对其进行存取和修改;

③ 定义全局变量是函数之间传递信息的手段。
实际编程时,尽量
避免使用全局变
量,不安全
2. 局部变量

① 仅在函数工作空间存在中间变量,影响仅限于函数本
身;
② 函数文件变量不能直接访问 workspace 中的全局变
量,它只能读取通过参数传入的变量;
③ 函数文件中定义的变量不能被另一个函数文件引用;
④ 如果在若干函数中,把某个变量定义为全局变量,那么
这些函数可以共用这个变量。
在 matlab 中,函数内部定义的变量除特殊声明外均为局部变量
3. 定义全局变量 global
调用格式: global 变量名 全局变量名一般大写字母;
(1) 编写矩阵元素和的均值程 变量之间以空格分隔

function avgs=test4(A)
( 2 )调用 test4 :
global S SS % 定义全
局变量 例 >> A=[4 3 5;6 7 8;3 5 7;1 3 4];
[m,n]=size(A); >> test4(A)
ans = 4.6667
for i=1:m
s(i)=sum(A(i,:)) % 每行 ( 3 )命令窗口中定义 S 和 SS 为全局变
量:
的和 >> global S SS
end >> ss
ss=sum(s) % 矩阵和 ss = 56
avgs=ss/(m*n) % 矩阵和 >> s
的平均值 s = 12 21 15 8
6/29/22 04:40 PM 31
end
如需某个变量在几个函数或 MATLAB 命令窗口中被使用,则用 global 在函数
编程和 MATLAB 命令窗口中都要声明该变量为全局变量。
3.3.3 主函数与子函数
 一个 M 文件可含多个函数 , 第一个主函数 , 其它子函
数;
 主函数必须在最前面,子函数次序可随意调整;

function
子函数仅被主函数或同一文件其它子函数所调用;
c=test(a,b) % 主函数
c=test1(a,b)*test2(a,b);
end 例
function c=test1(a,b) % 子函数 1
c=a+b;
end
function c=test2(a,b) % 子函数 2
c=a-b; 子函数则只能在主
end 函数文件中编辑

6/29/22 04:40 PM 32
3.3.4 函数句柄和匿名函数
1. 函数句柄 : 携带函数路径的函数,反复调用方便,
像变量调用。 x
函数表达式 y  x  10
① 两种创建句柄: function fv=fun(x)
fv=x-10.^x ;
end 定义函数文
hfun=@+ 函数名 件
>> hfun=@fun
>> hfun=str2func(‘fun’)
hfun=str2func(‘fun’)
>>class(hd)
ans =function_handle
② 函数句柄调用:
直接调用: 调用与函数一样,句柄变量名取代函数名
[y1, y2, ..] = hfun( x1, ..., xn)

>> hfun(3) ans =46.0977

feval 间接调用 : 执行由串指定的函数


[y1, y2, ..] = feval(fhandle, x1, ...,
xn)
>> feval(hfun,3) ans =46.0977
x
2. 匿名函数 函数表达式 y  x  10
特点: 不要求 M 文件,简单形式,
在命令窗口或者 M 文件中定义。
只含表达式、任意多输入和输出变量。

格式: f= @ (xlist)expression
① 以 @ 符号开头;
② xlist 为输入参数列表 yyy=@(x)x-10^x
③ expression 为表达式的函数体
调用和函数句柄一样: ff=@(x)x-10^x
>> ff(2) 或者 >> feval(ff,2)
x=0:0.1:1;
y1=sin(x);
y2=cos(x);
3.4 y=y1-y2;
最简单的程序结构,自动按 plot(x,y)
顺序结构 顺序执行文件的命令


控 3.4.1 条件(选择)结构

结 3.4.2 循环结构

3.4.3 try-catch 结构
3.4.1 选择(条件)结构

选择结构 : 根据给定条件成立与否,执行不同语句

选择结构的语句 :
if 语句 根据逻辑条件判断执行语句

switch 语句 根据条件值选择执行语句
1. if 条件语句
(1) 单分支结构
if expression (条件表达式:关系和逻辑运算
符)
statements (语句组 A )
end
(2) 双分支结构
if expression (条件)
statements1 (语句组 A )
else
statements2 (语句组 B )
end
x 
 2
x0
例计算分段函数值
例 y e
 2
 ln( x  1  x ) 0 > x
x=input(' 请输入 x 的值 :');
if x<=0
y=(x+sqrt(pi))/exp(2);
else
y=log(x+sqrt(1+x*x))/2;
end
fprintf('y=%e',y) %e 科学计算法形式实数输出
(3) 多分支结构
if expression1 (条件 1 )
statements1 (语句组 1 )


elseif expression2 (条件 2 ) 顺


statements2 (语句组 2 ) 次


... ...
elseif expressionm (条件 n )
statementsm (语句组 n )
else
statements (语句组 n+1 )
end
用条件语句 if 编写分段函数计算程序 , 分别求 (1)x=- 2 (2)x=
例 数 f 的值
 x 2  3* x  5 x0
 2
分段函 f ( x)   x  2 * x  6 0  x  5
数  x 2  5* x  6 5x>5
x

解: (1) 编写 M 文件
x=input(' 请输入 x 的值 :');
if x<=0
(2) 调用函数的运行结果:
y=x^2+3*x-5 请输入 x 的值 :-2
elseif x<=5 &x>0 y = -7
y=x^2-2*x+6; y=-7.000000e+000
else 请输入 x 的值 :5
y=2.100000e+001
y=x^2-5*x-6;
end
fprintf('y=%e',y)
2. switch 开关语句 数控的多路开关
1. switch 语句结构
switch expression (开关表达式) 2. switch 语句特点
case value1 (表达式 1 )
statement1 (语句组 1 )
 先按给定的变量计算开关表达
case value2 (表达式 2 ) 式 expression 的条件值,这
statement2 (语句组 2 ) 个值可以是标量也可以字符串
... ...  依次与各 case 指令比
case valuem (表达式 m ) 较。 Case 指令可以是标量或
statementm (语句组 m ) 字符串,
otherwise
还可以单元数组(元胞数组)
statement (语句组 n )
 比较结果为真时,执行相应语
end
句,再跳出 switch 结构。
条件值
 如多条 case 语句为真,也只执
行所第一条为真的语句。
 结果都为假,执行 otherwise
后的语句,再跳出 switch 。

根据评分原则:大于等于 90 分为 A ,大于等于 80 分为 B,
大于等于 70 分为 D ,大于等于 60 分为 C ,小于 60 分不
例 合格 (E2 ) switch 语句编
例 ( 1 ) if 语句编

function result=grade(per)

k=floor(per/10) % 开关表达式 function result=grade(x)
switch k if x>=90
case {9,10} floor 向负无穷取整 result='A';
result='A'; elseif x>=80
case 8 result='B';
result='B'; elseif x>=70
case 7 result='C';
result='C'; elseif x>=60
case 6 result='D';
result='D'; else
otherwise Case 语句表示数的result='E';
result='E'; end
end 范围采用 {}
( 3 ) switch 语句 per=input(' 输入成绩 ')
k=floor(per/10)
编写
switch k
第二种方法 case {9,10}
disp('A')
case 8
disp('B')
case 7
disp('C')
case 6
disp('D')
otherwise
disp('E')
end
3.4.2 循环结构
循环结构 : 按照给定的条件,重复执行指定的语
句。 Jacobi 迭代法求解线性方程的函数文件
循环结构的语 function [x,n]=jac(A,b,x0,eps)
if nargin==3
句: eps=1.0e-6; % 迭代精度
elseif nargin<3
for 语句 error
return
end
D=diag(diag(A)); % 求 A 的对角矩阵
L=-tril(A,-1); % 求 A 的下三角阵
U=-triu(A,1); % 求 A 的上三角阵
while 语句 B=D\(L+U);
f=D\b;
常用累计求和 x=B*x0+f; % 迭代解
n=1; % 迭代次数
求迭代等 while norm(x-x0)>=eps
x0=x;
x=B*x0+f;
n=n+1;
1. for 循环

for variable=expression( 循环变量 )


statement (循环体,执行语句)
end

< 循环次数设定 >

for 循环变量 = 初始值 : 步长 : 终止



循环体语句
end


采用循环语句会降
当 n=100 时,求 y 的值 低其执行速度,所
以程序通常由下面
累计求和 的程序来代替:

y=0; n=100; n=100;


for k=1:n i=1:2:2*n-1 无循环

y=y+1/(2*k-1); x=1/.i % 数组运算还是矩阵运算


end y=sum(x) % 求和
y y
一个三位整数各位数字的立方和等于该数本身则
称该数为水仙花数。输出全部水仙花数。


for m=100:999
m1=fix(m/100); % 求 m 的百位数字
m2=rem(fix(m/10),10); % 求 m 的十位数字
m3=rem(m,10); % 求 m 的个位数字
if
m==m1*m1*m1+m2*m2*m2+m3*m3*m
3
disp(m) Fix 向零取证
end
end Rem 除法求

2. For (while) 循环语句分配数组

为得到最大速度 , 在 For (while) 循环被执行之前 , 应预先分配数


组.
建议用 zeros 或 ones 等命令预先分配所需内存(即向量矩阵大
( 1 )程序: 例 ( 2 )运行结果:
小)。
x=zeros(1,3) x= 0 0 0
for n=1:3 x = 0.3090 0 0
x(n)=sin(n*pi/10) x = 0.3090 0.5878 0
end x = 0.3090 0.5878
x 0.8090
x = 0.3090 0.5878
0.8090
x = rand(1,50000); % 随机投币 50000 次
sum=0; % 投币次数累计值初始值为 0 投掷硬币实验
k1=0; % 投币正面次数累计值初始值为 0
例 a=zeros (1,50000); % 投币正面次数累计值分配数组
b= zeros (1,50000); % 投币次数累计初始值占位,
for (i=1:50000) 随机 0 ~ 1 间
sum=sum+1; % 投币次数累计值 矩阵 均匀分布
if x(i) > 0.5 % 投币正面概率 > 0.5 rand
k1=k1+1; % 投币正面次数累计值
end
a(i)=k1; % 投币正面次数累计值
b(i)=sum; % 投币次数累计值
end 出现反面的频率变化曲线

f1=a./b; % 正面概率 0.7

figure(1) 0.6

plot(b,f1),title(' 出现正面的频率变化曲线 ')


0.5

figure(2) 0.4

plot(b,1-f1),title(' 出现反面的频率变化曲线 ')


0.3

k1% 正面次数 ,k2=sum-k1 % 反面次数 0.2

f1=k1/sum % 正面频率, f2=1-f1 % 反面频率


0.1

0
0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5
4
x 10
3.break 和 continue

 break 和 continue 与循环结构 for 和 while 语句相关,

它们一般与 if 配合使用。

 break 终止循环,即跳出该层循环 ;

 continue 结束本次循环,进行该层下次循环 .


求 [100 , 1000] 之间第一个能被 21 整除的整数。

for n=100:1000
if rem(n,21)~=0
continue Rem 除法求余
end
break
end
n
3. while 循环 < 逻辑判断语句
>
while expression ( < 逻辑变量 > )
statement (执行语句的循环体)
end

例 编程: 求 n 为多少
n=0; 时, 2^n>100, 其
while 2^n<100
值多少
s=2^n; 运行结果
n=n+1 ; >>Ss = 128
end n= 7
Ss=2*s >> s
n s = 64
function [x,n]=jaco(A,b,x0,eps)
if nargin==3
eps=1.0e-6; % 迭代精度
elseif nargin<3
error
return
end
D=diag(diag(A)); % 求 A 的对角矩阵
L=-tril(A,-1); % 求 A 的下三角阵
U=-triu(A,1); % 求 A 的上三角阵
B=D\(L+U);
f=D\b;
x=B*x0+f;
n=1; % 迭代次数
while norm(x-x0)>=eps Jacobi 迭代法的
x0=x; MATLAB 函数文件
x=B*x0+f; Jacobi.m
n=n+1;
end
4.for 和 while 循环语句区别

 for 适用已知到循环次数,而不知循环运算目标;

 while 适用已知循环运算目标,而循环次数未知 ;

 为了提高代码的运行效率,避免 for 循环的使


用。

6/29/22 04:40 PM 55
63
计算级数 :S=1+2+2 +2 +···+2 = 
n
例 2 3 2 63
例 n 0

s=0; (1)for 语句 s=0; (2)while 语句


i=0; i=0;
for i=1:63 while i<64
s=s+2^i; s=s+2^i;
i=i+1;
end
i=i+1;
s end
i s
i

6/29/22 04:40 PM
56
从键盘输入若干个数,当输入 0 时结束输入,求

例 这些数的平均值和它们之和。
sum=0;
cnt=0;
val=input('Enter a number (end in 0):');
while val~=0
sum=sum+val;
cnt=cnt+1;
val=input('Enter a number (end in 0):');
end
if cnt > 0
sum
mean=sum/cnt
end
总结
3.4.3 try-catch 语句
语句格式 Try
try ① 检测程序代码是否出
语句组 1
错;
catch
语句组 2 ② 先试探语句组 1 ,如出
end 现错误,则将错误信息
赋给 lasterr 保留;
lasterr % 显示出错原因
③ 并转去执行语句组 2 。
矩阵乘法运算要求两矩阵维数相容,否则会出错。先


求两矩阵的乘积,若出错,则自动转去求两矩阵的点
乘。

编程: 运行结果:
A=[1,2,3;4,5,6]; B=[7,8,9;10,11,12]; C = 7 16 27
try 40 55 72
C=A*B; ans = 错误使用 *
catch 内部矩阵维度必须一
C=A.*B; 致。
end
C
lasterr % 显示出错原因
Matlab实用教程(高等院校精品教材) 周明华 主
3.5 程序调试 编
出版社 : 浙江大学出版社 出版时间 :2013-12-01

3.5.1 人机交互命令

编程或调试程序中常用到能实现特殊功能的
命令,实现交互式调试方式,主要有
echo 、 keyboard 、 return 、 pause
等。
1. echo M 文件命令执行时可见

执行 M 文件时,通常在命令窗口是看
不到 M 文件命令和执行过程的,但在调试程序时
需要执行 M 文件同时在命令窗口显示每条命令。
这时可以用 echo 命令实现这样的功能。
Echo 常用的命令
echo 命令
脚本文件

函数文件
脚本文件显示 函数文件显示
>> echo on
>> ed % 调用脚本文件 例如:
例如: for for n=100:1000
n=100:1000 if rem(n,21)~=0
function [c,d]=abcd(a,b)
if continue c=a+b 解释执行
rem(n,21)~= if rem(n,21)~=0 d=sin(c)
0 continue
e=log(d)
continue if rem(n,21)~=0
end continue end 保存函数文件 abcd
break if rem(n,21)~=0 >> echo abcd on
continue >> abcd(2,3)
end if rem(n,21)~=0 function
n continue [c,d]=abcd(a,b)
if rem(n,21)~=0 c=a+b
保存脚本 end c= 5
ed break d=sin(c)
end 编译执行 d = -0.9589
n e=log(d)
e = -0.0419 +
n= 3.1416i
end
105 ans = 5
function [x,n]=jaco(A,b,x0,eps)
if nargin==3
eps=1.0e-6; % 迭代精度
elseif nargin<3
error
return
end
D=diag(diag(A)); % 求 A 的对角矩阵
L=-tril(A,-1); % 求 A 的下三角阵
U=-triu(A,1); % 求 A 的上三角阵
B=D\(L+U);
echo jacw on
f=D\b;
[xx,nn]=jacw([10,-1,0;-1,10,-2;0,-2,10],[9,7,6]',[0;0;0])
x=B*x0+f;
n=1; % 迭代次数
while norm(x-x0)>=eps
x0=x;
x=B*x0+f;
n=n+1;
end
2. keyboard 便于程序调试和运行中修改变量

① 程序遇到 keyboard 命令,停止程序行 , 控制权给键盘,等


待键盘输入,命令窗口“ >>” 变成“ K>>”
② 处理完毕后,键入 R, 程序继续运行
编程:
function e=abcdek(a,b) 运行结果:
abcdek(4,2)
c=a+b; K>> a=2
keyboard a= 2
d=a*b K>> return
d= 4
e=a/b e= 1
end
dbquit 退出 K >>
3. return 直接退出程序或函数返回

function [x,n]=jaco(A,b,x0,eps)
if nargin==3
eps=1.0e-6; % 迭代精度
elseif nargin<3
error
return % 错退出程序
end
D=diag(diag(A)); % 求 A 的对角矩阵
L=-tril(A,-1); % 求 A 的下三角阵
Jacobi 迭代法的
U=-triu(A,1); % 求 A 的上三角阵
MATLAB 函数
B=D\(L+U);
文件 Jacobi.m
f=D\b;
x=B*x0+f;
n=1; % 迭代次数
while norm(x-x0)>=eps
x0=x;
x=B*x0+f;
n=n+1;
end
4. 程序的暂停 pause
pause(n) 或
pause
 n 是延迟时间,以秒为单位;
 缺省,将暂停程序,直到用户按任意键后继续

 pause off 屏蔽程序中所有 pause 的作用


 pause on 打开 pause 的作用

若想强行终止程序的运行,可以使用 Ctrl+c
例 一般程序:
例 function
[e]=abcde(a,b)
c=a+b
d=sin(c) 暂停命令的程序:
e=log(d) function
end [e]=abcdep(a,b)
c=a+b 运行结果:
d=sin(c) >> abcdep(3,4)
pause c= 7
e=log(d) d = 0.6570
end 任意键
e = -0.4201
3.5.2 编程中注意事项
M 文件错误种类:
语法错误:函数参数输入类型,括号, matlab 直接指出
运算逻辑错误 :运行过程死机或溢出,与程序本身有关。

M 文件设计应避免情况: Inf , nan 或空矩阵


避免方法: 可能异常地方提供识别语句
识别语句: isinf, innan, isempty
3.5.3 断点调试
MATLAB 提供一系列程序调试命令,用这些命令可以
在调试过程,设置、清除和列出断点,逐行运行 M 文
件,在不同的工作区检查变量,用来跟踪和控制程序的
运行,帮助寻找和发现错误。
设置断点,使得程序在断点前自动
停止执行,并进入调试模式,从而
可以检查当前各个变量的值。
1. 设置断点
 dbstop if error
遇到错误时,自动设置断点。不包括 try…catch 之间的错误。
 dbstop if all error
遇到错误时,自动设置断点。包括 try…catch 之间的错误。
 dbstop if caught error
try…catch 间代码遇到错误时,自动设置断点 。
 dbstop if naninf 或 dbstop if infnan
当程序运行遇到无穷值或者非数值时,自动设置断点。
 dbstop if warning
遇到警告时,自动设置断点
 dbstop in mfile
文件名为 mfile 的 M 文件的第一个可执行语句前设置断
点。
 dbstop in mfile at lineno
mfile 的 M 文件的第
lineno 行设置断点。如果第 lineno 行为非执行语句,则在
其后的第一个可执行语句前设置断点。
 dbstop in mfile at subfun
mfile 的 M 文件子程
序 subfun 第一个执行语句前设置断点。
2. 其它调用函数
 dbtype 显示行号的 M 文件文本
 dbstatus 显示断点信息
 dbcont 继续执行 到程序结束,或者下个断

 dbstep 将从断点处继续执行 M 文件
 dbclear in mfile 清除断点
 dbquit 退出调试状态
3. 使用命令调试程序 function y=ttt(x)
(1) 被调试程序 ttt : q=length(x);
y={1:q}+x
end

(2) 命令窗口输入断点方式: dbstop in ttt,


(3)edit 打开 ttt.m,

第一个可执行语句前
红点即设置断点。
( 4 )单击图中红点,会发现红点被取消,此时
回复到初始状态。
( 5 )命令窗口依次输入 dbstop if error 和 调
用 ttt(magic(3))

指向出错的程序行
Dbquit 退出

You might also like