4.1条件语句
4.1.1 if-elseif-else-end语句
易错点:elseif关键字中间不能加空格,不能写成else if,这和C、Java等语言不同。
注意:在使用if语句时,if和end这两个关键字是无论如何都不能省略的。而elseif和else可以根据自己的需要来决定是否添加。
如果if和elseif后面表达式的计算结果为非零数值,就会被当成true;如果计算结果为数值零,则会被当成false。
另外,在if或elseif后面放上了一个矩阵或者向量,这时候只有当这个矩阵或者向量中的所有元素都是非零元素时,才会被当成true。
% 给定一个同学的成绩(假设为整数),输出这个同学的等级。等级规则如下:
% 90至100分为1级、80至89分为2级、60至79分为3级、低于60分为4级;
% 如果成绩小于0分或者大于100分,则代表成绩输入有误,此时等级为0。
x = 110;
if x>=90 & x<=100
dj = 1
elseif x>=80 & x<90
dj = 2
elseif x>=60 & x<80
dj = 3
elseif x<60
dj = 4
else
disp("成绩输入有误")
end
%另外,假设我们不考虑输入有误的情况,x全都取在0至100之间时:
x = 56;
if x>=90 & x<=100
dj = 1
elseif x>=80 & x<90
dj = 2
elseif x>=60 & x<80
dj = 3
else
disp("成绩不合格")
end
%我们可以对if和elseif后面的判断条件进行简化(在不考虑有误的情况下):
x = 78;
if x>=90
dj = 1
elseif x>=80
dj = 2
elseif x>=60
dj = 3
else
disp("成绩不合格")
end
% (1)给定包含2个元素的行向量a,请使用if语句对向量a中的元素按照从小到大的顺序排序,
% 并将排序后的向量保存为变量sort_a。例如a = [5,3],那么sort_a = [3,5]。
a = [4,2];
if a(1)>a(2)
sort_a = [a(2),a(1)]
else
sort_a = a
end
%或者
a = [4,2]
if a(1)>a(2)
sort_a = [a(2),a(1)]
elseif a(1)<a(2)
sort_a = a
end
% (2)给定一个包含2个元素的行向量a,请对向量a中的元素按照从小到大的顺序排序,
% 将排序后的结果直接赋值到a上,不需要使用新的向量保存排序结果。
a = [4,2];
if a(1)>a(2)
a = [a(2),a(1)]
else
a
end
x = [1 2;0 3];
if x
a = 10;
else
a = 20;
end
a
x = [1 2;-1 3];
if x
a = 10;
else
a = 20;
end
a
%思考题:修改上面的代码使得:当x中至少有一个元素为非零元素时,就会被当成true
x = [1 2;0 3];
if any(x(:))
a = 10;
else
a = 20;
end
a
% 例题:已知a、b和c是三个互不相等的常数,请使用条件语句找出a、b和c三个数的最大值。
% (注意,这里是练习条件语句,请不要使用max函数直接求最大值)
a = randi(1000,1,1)
b = randi(1000,1,1)
c = randi(1000,1,1)
if a>b & a>c
m = a;
elseif b>a & b>c
m = b;
elseif c>a & c>b
m = c;
end
m
%使用嵌套
if a>b
if a>c % 此时a>b且a>c
Max=a;
else % 此时a>b且c>a
Max=c;
end % a>c前面的那个if配套的end,通过缩进可以看出
else % 此时a<b
if b>c % 此时a<b且b>c
Max=b;
else % 此时a<b且b<c
Max=c;
end % b>c前面的那个if配套的end,通过缩进可以看出
end % 最上方的if配套的end
小技巧:利用智能缩进整理代码,选中代码后按快捷键“ctrl+i”,也可以选中代码后右键找到智能缩进。
4.1.2 switch-case-otherwise-end语句
switch语句在运行时,会将开关表达式的值依次和各个 case后面的表达式的值判断是否相等,如果相等则为true,此时会执行该case中相应的语句;如果不相等则为false,此时会取下一个 case 后面表达式的值进行比较,直到出现true为止。如果所有case 后面表达式的值均与开关表达式的值不相等,则执行 otherwise 中对应的语句。
s = randi([1,4])
switch s
case 1
disp("春季")
case 2
disp("夏季")
case 3
disp("秋季")
otherwise 4
disp("冬季")
end
%a和b是在区间[1,10]上随机生成的两个整数,
% 我们希望根据变量way表示的字符串决定对a和b的计算方式。
a = randi([1,10])
b = randi([1,10])
way = "加法"
switch way
case "加法"
c = a + b
case "减法"
c = a - b
case "乘法"
c = a * b
case "除法"
c = a / b
end
%转换成if语句
a = randi([1,10])
b = randi([1,10])
way = "加法"
if way == "加法"
c = a + b
elseif way == "减法"
c = a - b
elseif way == "乘法"
c = a * b
elseif way == "除法"
c = a / b
end
字符串和字符串向量,单引号是字符向量,双引号是字符串。
%字符向量的比较
'abc' == 'abc' %ans = 1×3 logical 数组
strcmp('abc','acb') %ans = logical 0
strcmp('abc','abc') %ans = logical 1
%字符串
"abc" == "abc" %ans = logical 1
n = randi([0,100]) % n是区间[0,100]上的随机整数,表示成绩
switch true
case n>=60
disp("成绩合格")
otherwise
disp("成绩不合格")
end
% case后面的表达式可以是一个元胞数组,
% 如果switch后面开关表达式的值和case元胞数组中的至少一个元素相同,则为true
month = randi([1,12])
switch month
case {1,2,3}
season = "春天"
case {4,5,6}
season = "夏天"
case {7,8,9}
season = "秋天"
case {10,11,12}
season = "冬天"
end
disp(season) %disp(X) 显示变量 X 的值,而不打印变量名称。
%补充
num2cell([1:3]) %等价于{1,2,3}
% 再来一个输出成绩等级的例子。若n表示考试成绩(假设n为0至100的整数,不考虑输入错误的情况),
% 其中90~100分等级为A,80~89分等级为B,70~79分等级为C,60~69分等级为D,60分以下不及格,
% 请使用switch语句输出某一具体分数对应的等级。
n = randi([1,100])
switch true
case n>=90
dj = "A"
case n>=80
dj = "B"
case n>=70
dj = "C"
case n>=60
dj = "D"
otherwise
dj = "不合格"
end
disp(dj)
%转换成if
n = randi([1,100])
if n >= 90
disp("A")
elseif n >= 80
disp("B")
elseif n >= 70
disp("C")
elseif n >= 60
disp("D")
else
disp("不及格")
end
4.2循环语句
4.2.1.for-end语句
4.2.1.1 for-end语句(简称for循环)
用于事先已知循环次数的情形:
在该语法中,循环变量是用于迭代的变量名,它会在每次循环迭代中从向量或矩阵中取出一列的值。数值向量或者矩阵则表示了循环变量可以取值的范围,通常根据实际需要事先给定。一旦循环变量遍历完数值向量或者矩阵中的所有值,循环就会结束。
4.2.1.2例题
(1)不使用sum函数,计算行向量x中所有元素的和。
s = 0;
x = [5 8 9 1 4 3 7];
for i = x
s = s + i;
end
disp(s)
(2)如果x是一个列向量,左侧的代码输出的s是什么,应该如何修改代码?
s = 0;
x = [3;5;9;8];
for i = transpose(x)
s = s + i;
end
disp(s)
(3)计算当n等于100时,下面式子的结果:
写成求和形式:
x = 1:100;
k = 0;
x1 = 1 ./ (x .^2);
for i = x1
k = k + i;
end
disp(k)
(4)计算当n从1一直取到100时,上一小问式子的计算结果,
并将计算结果保存到一个长度为100的行向量S中。
S = zeros(1,100);
for n = 1:100
y = 0;
for k = 1:n
y = y + 1 / (k^2);
end
S(n) = y;
end
disp(S)
%优化后,不嵌套循环
S = [];
y = 0;
for k = 1:100;
y = y + 1 / (k^2);
S = [S,y]
end
disp(S)
(5)计算从公元1年到公元9999年间,有多少个闰年。闰年的判读条件是年份能够被4整除,但不能被100整除,或者年份能够被400整除。
R = [];
for n = 1:9999
if (mod(n,4) == 0) & (mod(n,100) ~= 0)
R = [R,n];
elseif mod(n,400) == 0
R = [R,n];
end
end
num = sum(logical(R)) %闰年的数量,闰年的年份储存在了S向量中。
(6)一个三位正整数各位数字的立方和等于该数本身则称该数为水仙花数,例如:1^3 + 5^3+ 3^3 = 153,则153是水仙花数。请你找出所有的水仙花数并将其保存到向量S中。
S = [];
for n = 100:999
N = num2str(n);
N1 = str2num(N(1));
N2 = str2num(N(2));
N3 = str2num(N(3));
if N1^3 + N2^3 + N3^3 == n
S = [S,n];
end
end
disp(S)
(7)斐波那契数列的递推公式为,求F(30)。
F = ones(1,30);
for n = 3:30
F(n) = F(n-1) + F(n-2);
end
disp(F(30))
(8)生成一个5行8列的矩阵,矩阵中每个元素都是在区间[1, 10]上取值的随机整数。接下来请循环每一列,若发现同一列的五个元素各不相同,则保留该列;若该列中有重复的元素则删除该列。
A = randi([1,10],5,8);
B = [];
for a = A
a1 = diff(sort(a));
if sum(logical(find(~a1))) == 0
B = [B,a];
end
end
B
4.2.1.3注意事项:
(1)若for语句后面的向量或者矩阵为空,则循环一次也不会被执行。
(2)for语句后面的向量或者矩阵只会在循环开始时使用一次,向量或者矩阵元素一旦确定将不会再改变。即使你在循环体中改变向量或者矩阵的值,循环变量的值也不改变。
(3)可以在循环体中修改循环变量的值,但当程序执行流程再次回到循环开始时,循环变量会自动恢复成向量或者矩阵的下一列元素。
4.2.2.while-end语句
4.2.2.1while语句
除了for-end语句之外,MATLAB还提供了另一种强大的循环语句:while-end语句(简称while循环)。与for循环不同,while循环的特点在于它允许我们在不知道具体循环次数的情况下执行循环体,这种灵活性使得while循环在某些情境下非常有用,尤其是当我们需要满足某些某些条件时才执行循环操作。
y = 1;
n = 1;
while y <= 10
n = n + 1;
y = y + 1/n;
end
disp(n)
a(1) = 1;
a(2) = 1;
n = 2;
while a(n) <= 9999;
n = n + 1;
a(n) = a(n-1) + a(n-2);
end
disp(a(end))
y = 1;
n = 1;
while n < 100
n = n + 1;
y = y + 1/n;
end
disp(y)
4.2.2.2注意事项:
(1)如果不小心执行了一个无限循环(即永远不会自行结束的循环,又称死循环),
可以按下 Ctrl+C 停止执行程序。
(2)while后面表达式的计算结果不一定非得是逻辑值1或0。如果表达式的计算结果是一个数值常数,则只有当这个常数为非零值时循环才会进行;若表达式的计算结果是一个数值向量或者矩阵,则仅当该向量或矩阵中的所有元素都是非零数时循环才会进行。
4.2.3.break和continue
4.2.3.1关键词介绍
- break关键字用于终止执行 for 或 while 循环。
- continue关键字用于跳过循环的当前迭代,然后继续下一次迭代。
n = 1e8;
S = 0;
for k = 1:n
S = S + 1/k;
if S > 10
disp(k)
break
end
end
(2)使用循环输出1至10中所有的奇数。
for i = 1:10
if mod(i,2) == 0
continue
else
disp(i)
end
end
注意,如果存在循环的嵌套,break和continue 仅在调用它的循环的主体中起作用。即break 仅从它所发生的循环中退出,continue 仅跳过它所发生的循环体内的剩余语句。
4.2.3.2例题
(1)判断质数问题
n = 135389; % 输入要判断的数n
is_prime = true; % 初始化标志变量is_prime为true,此时代表n是质数
for ii = 2:n-1 % 思考:如何缩小循环遍历的范围来提高代码运行的效率,留作本章课后习题
% 检查ii是否能够整除n
if mod(n, ii) == 0
% 如果能整除,则n不是质数,将标志变量is_prime重新赋值为false
is_prime = false;
break; % 跳出循环
end
end
(2)扑克牌炸弹问题
A = [1:13];
poke = [repmat(A,1,4),14,15];
k = 1;
while true
ind = randperm(54,17);
nmp = sort(poke(ind));
v1 = all(ismember([14,15],nmp));
v2 = false;
for i = 1:13
if sum(nmp == i) == 4
v2 = true;
break
end
end
if (v1 | v2) == 1
break
else
k = k + 1;
end
end
disp(k)
(3)一只失明的小猫掉进山洞里,山洞有三个门,其中进入第一个门后走2h后可以回到地面,进入第二个门后走4h会回到原始的出发点,进入第三个门后走6h还是回到原始的出发点。假设小猫每次都随机地选择这三个门中的一个进入,求小猫走出山洞的期望时间?
n = 10000 % 设置模拟的次数
T = zeros(1,n); % T用来存储每次模拟得到的时间
for k = 1:n % 开始进行 n 次模拟
t = 0 % 初始化时间
while true % 开始模拟小猫走出山洞的过程
m = randi([1,3]); %随机选择第几个门
if m == 1 % 选择第1个门
t = t + 2; % 走2小时回到地面
break % 小猫成功走出山洞,结束模拟
elseif m == 2 % 选择第2个门
t = t + 4; % 走4小时回到原始出发点
elseif m == 3 % 选择第3个门
t = t + 6; % 走6小时回到原始出发点
end
end
T(k) = t; % 记录每次模拟得到的时间
end
E = mean(T) % 计算所有模拟结果的平均值,即小猫走出山洞的期望时间的估计
(4)二分搜索法求函数零点
f(x)在区间[6,10]递增且f(6)< 0 ,f(10)>0,请用二分搜索法求零点x0(f(x0)和0的误差控制在1e-8内即可)。
a = 6;
b = 10;
vol = 1e-8;
while true
c = (a + b) / 2;
fc = c^3-8*c^2+c-5;
if abs(fc) <= vol
x0 = c
break
end
if (a^3-8*a^2+a-5) * fc < 0;
b = c;
elseif (b^3-8*b^2+b-5) * fc < 0;
a = c;
end
end
4.3处理异常的 try-catch 语句
4.3.1.try-catch语句
在编写 MATLAB程序时,我们需要考虑程序的健壮性和容错性。有时候,我们编写的程序会出现意想不到的错误或异常情况,如数据输入错误、文件读取问题、网络连接错误等。为了更好地处理这些异常情况,MATLAB 提供了一种强大的工具,即try-catch语句,它允许我们在代码块中尝试执行可能会引发异常的操作,并在异常发生时捕获并处理它们,而不会导致程序报错终止。
如果try中编写的代码发生了异常,转而运行catch中的语句。
A = ones(3,3);
B = ones(5,5);
C = A + B %会报错"对于此运算,数组的大小不兼容。"
D = 1 + 2 %上边的报错,下面这一行代码就无法运行。
A = ones(3,3);
B = ones(5,5);
try
A + B
catch
disp("大小不兼容哦,无法计算!")
end
D= 1 + 2 %这行代码就可以运行
M = rand(4,4)
r = 6;
try
r = r*2;
x = M(r, :) % 取M的第r行元素
catch aaa
x = [] % 若M没有第r行元素,则返回空向量
end
aaa
lasterr
%aaa =
MException - 属性:
identifier: 'MATLAB:badsubscript'
message: '位置 1 处的索引超出数组边界。索引不能超过 4。'
cause: {}
stack: [0×1 struct]
Correction: []
注:lasterr 函数能够返回 MATLAB 生成的最后一条错误消息,尽管这个错误已经被代码中的 try-catch 语句捕获了。
上面两个应用 try-catch语句的例子比较简单下面给大家描述一些常见的应用try-catch语句捕获异常的场景。
(1)文件操作异常:例如MATLAB 在读取或写入本地文件时容易出现文件不存在、文件被占用、读取或写入权限不足等问题。
(2)数据处理异常:例如题目给的数据中有1000条字符串,我们需要通过某个函数来提取这 1000条字符串中的数据,但有少数几条字符串在提取数据时会报错,需要单独处理。
(3)网络通信异常:在使用 MATLAB执行爬虫操作时(爬取网站上的数据),可能出现的一些网络错误,如网络连接超时、ip被封禁等。
(4)GUI应用异常:在GUI(即图形用户界面)应用程序中处理用户输入或操作可能引发的异常,例如某个输入框中需要用户输入一个数字,结果用户输入了一个字符串。
(5)信号处理异常:在信号处理或实时控制系统中,可能需要处理硬件故障或信号丢失等异常情况。
(6)数据库操作异常:MATLAB与数据库交互时,可能会出现连接中断、SOL查询错误或数据不一致等异常。
这些不同的应用场景都可以受益于try-catch语句,处理可能的异常情况能够提高程序的可靠性,也能给使用程序的其他用户提供更好的体验。
4.4控制程序流程的其他常用指令
4.4.1.程序运行计时:tic/toc
tic 和 toc 是一对用于计时的MATLAB指令,你需要将tic和toc分别放在需要计时的代码段的前面和后面,运行代码后MATLAB就会输出这段代码的运行时长,单位为秒。
tic
A = rand(1000);
B = rand(1000);
%C = []; % 历时 0.168304 秒。
C = zeros(1000,1000); % 历时 0.029817 秒
for i = 1:1000
for j = 1:1000
if A(i,j)> B(i,j)
C(i,j) = A(i,j) + B(i,j);
else
C(i,j) = A(i,j) .* A(i,j);
end
end
end
toc
%用矩阵运算比循环结构快很多
tic
C2 = (A > B).*(A+B) + (A <= B).*(A.*B); % 历时 0.002782 秒。
toc
4.4.2.暂停程序运行:pause
pause 函数用于暂停程序的运行,当程序运行到该命令时,程序暂时中止。它的调用格
式有下面两种:
(1)pause:暂时停止代码的执行,等待用户按任意键继续运行:
(2)pause(n):暂停程序运行n秒。
A = 1+2
pause
B = 2+3
A = 1+2
pause(3) %暂停3秒
B = 2+3
while true
x = randi([1,10],1)
pause(1)
if x == 10
break
end
end
4.4.3.用户输入数据:input
编写 MATLAB 程序时,有时需要从用户那里获取输入的数据,以便程序根据这些数据执行不同的操作或计算。MATLAB 提供了 input 函数接收来自用户的输入数据,这在创建交互式程序或需要用户提供输入的情况下非常有用。input函数有下面两种调用方式:
x= input(提示用户输入的文本)
txt = input(提示用户输入的文本,'s')
第一种方式只需要给一个输入参数,即一个提示用户输入的文本,此时 MATLAB 的界面会显示这段文本,并等待用户输入值后按回车键确定。用户可以输入10、pi/4、rand(3)、1:10、[1,2;3,4]之类的数据或表达式,还可以输入工作区中已有的变量。
第二种方式有两个输入参数,这时候input 会将用户的输入看成文本格式,返回的变量txt是字符向量格式,这对于获取纯文本的输入非常有用。
注意:提示用户输入的文本请使用字符向量(单引号引起来)的形式,如果使用字符串(双引号引起来)则在较低的 MATLAB 版本中运行会报错。
r = input('请输入圆的半径:')
S = pi*r*r
a = input('请输入a的值:');
b = input('请输入b的值:');
way = input('请输入方式(乘法或者加法):','s');
if way == '乘法'
c = a * b;
elseif way == '加法'
c = a + b;
else
c = [];
end
disp(c)
4.4.4.显示警告信息:warning
编写 MATLAB程序时,警告信息是一种有用的反馈机制,可以用来提示用户在程序执行过程中可能存在的问题或不规范的操作。MATLAB 提供的 warning 函数用于显示警告信息。警告消息不会中断程序的执行,但它可以帮助用户和开发人员注意到潜在的问题,以便及时采取措施来解决。首先介绍 warning函数最常见的用法:warning of和 warning on,它们分别用于关闭和打开 MATLAB 的警告信息。
warning on % 默认是打开的
A = [3 6; 4 8];
A1 = inv(A) %警告: 矩阵在工作精度内为奇异的。
warning off
A = [3 6; 4 8];
A1 = inv(A) %不显示警告信息
warning on % 重新开启警告功能
a = input('请输入常数 a:');
b = input('请输入常数 b:');
if b == 0
warning('分母不应为0')
end
c = a/b
4.4.5.显示报错信息:erro
在 MATLAB 编程中,当程序遇到严重错误或不符合预期条件时,可以使用error 函数显示自定义的报错消息,并终止程序的执行。error 函数的用法很简单:error(报错信息),这里的报错信息请使用字符向量(单引号引起来)的形式,如果使用字符串(双引号引起来)则在较低的MATLAB版本中运行会报错。下面我们举个例子:a和b是用户输入的两个常数,计算a除以b的值,如果b等于0,则显示报错:分母不应为0。
a = input('请输入常数 a:');
b = input('请输入常数 b:');
if b == 0
error('分母不应为0')
end
c = a/b
参考:数学建模清风老师《MATLAB教程新手入门篇》https://www.bilibili.com/video/BV1dN4y1Q7Kt/
标签:disp,语句,end,10,程序流程,case,循环,matlab,第四章 From: https://blog.csdn.net/weixin_63883130/article/details/143472963