在编写程序时,有时我们需要根据不同的条件执行不同的命令。举个例子, b 站上有许多电影需要开通会员后才能观看完整的内容。在这种情况下, b 站后台会自动
检查观众是否是会员用户, 如果是会员, 则允许他们观看整个电影, 否则只允许试看几分钟。这个过程可以用右侧的流程图来表示,图上有左右两个分支。
在 MATLAB  中,我们将介绍两种条件语句: if-elseif-else-end  语句和 switch-case- otherwise-end 语句,它们可实现分支结构。其中前者更为通用,能够满足多种条件判断的需 求, 因此常用于实际编程中。无论使用哪种条件语句, 其核心思想都是一样的:首先判断给 定的条件是否满足,然后根据判断结果(true 或 false)执行相应的命令。
因此, 条件语句也可以被称为条件判断语句或判断语句,它们在程序中扮演着至关重要的角色,帮助我们实现不同情况下程序的灵活控制和处理。

4.1.1 if-elseif-else-end 语句

if、elseif、else 和 end 是 MATLAB 中的四个关键字,在第二章中我们强调过:不能定义与 MATLAB 关键字同名的变量。这四个关键字就构成了我们要学的第一种条件语句,后续我 们将其简称为 if 语句
易错点: elseif 关键字中间不能加空格, 不能写成 else if,这和 C、Java 等语言不同。
注意:在使用 if 语句时, if 和 end 这两个关键字是无论如何都不能省略的。有很多新手 在使用 MATLAB 时都会漏掉 end 这个关键字,导致后续无论输入什么命令 MATLAB 都没有 反应,而 elseif 和 else 可以根据自己的需要来决定是否添加。
下面我们先看一个完整的 if 语句的示例(假设有四个分支),其对应的流程图见右侧:
notion image
注意,这里的语句 1、语句 2、语句 3 和语句 4 最终只能有一个被执行。如果表达式 1 成 立(通常表达式返回一个逻辑值,值为逻辑值 1 则表示成立),则执行语句 1,后面的表达式 都不用判断,它们对应的语句也都不会被执行;如果表达式 1  不成立,则会接着判断表达式 2 是否成立,如果表达式 2 成立则会执行语句 2,否则会接着判断表达式 3 是否成立,如果表 达式 3 成立则会执行语句 3,如果表达式 3 也不成立则会执行语句 4。
notion image
想象成如下场景:给定一个同学的成绩(假设为整数),输出这个同学的等级。等级规则如下: 90 至 100 分为 1 级、80 至 89 分为 2 级、60 至 79 分为 3 级、低于 60 分为 4 级;如果成绩小  于 0 分或者大于 100 分,则代表成绩输入有误,此时等级为 0。
那么,应该怎样用 MATLAB 表示这个分段函数呢?不熟练的同学可以先画一个流程图, 其对应的 MATLAB 代码如右侧所示:
notion image
上面代码中有一些要说明的点:
(1) 判断 x 是否位于[90,100]这个区间时,不能写成 90<=x<=100 ,MATLAB 不支持这 种连续的判断。因此我们将其拆分成两个条件:x>=90 && x<=100。这里用的是 具有短路功能的逻辑与运算符&&,这样判断效率会更高。
(2) if 只能有一个,但 elseif 可以有多个, 它们后面都需要跟上相应的判断条件。 只有 在 if 后面的条件不满足时,才会判断 elseif 后面的条件是否成立。
(3) else 后面不能加上条件,当 if 和 elseif 后面的条件全部都不满足时,才会执行 else 对应的语句。
(4) 不需要在 if、elseif、else 和 end 所在的行的最后面添加冒号或者分号。
另外, 假设我们不考虑输入有误的情况, 即确保 x 的取值范围在 0 至 100 之间时,我们 可以对 if 和 elseif 后面的判断条件进行简化。显然, 可以去掉 if 后面的 x<=100,因为 x 的取 值范围已经固定了; elseif 后面的条件也能被简化, 以第一个为例, 原来代码中的判断条件写 的是 x>=80 && x<90,实际上我们可以直接写成 x>=80,这是因为只有当前面的判断条件都 不成立时才会到达当前的判断条件,而前面的判断条件不成立时意味着 x<90 。类似地,第二 个 elseif 后面的条件都能简化成x>=60,下面给出简化后的代码:
notion image
前文提到过: 使用 if 语句时, if 和 end 这两个关键字是无论如何都不能省略的, 而 elseif 和 else 可以根据自己的编程需要来决定是否添加。下面我们来举两个例子:
(1)给定包含 2 个元素的行向量 a ,请使用 if 语句对向量 a 中的元素按照从小到大的顺 序排序, 并将排序后的向量保存为变量 sort_a 。例如 a = [5,3],那么 sort_a = [3,5]。
我们只需要判断一次: 如果 a  中第一个位置的元素比第二个位置的元素大, 那么就调换 它们的位置并将结果赋值给 sort_a ;如果 a  中第一个位置的元素小于等于第二个位置的元素 则不用调换,直接将 a 赋值给 sort_a 即可,这时候就不需要用到 elseif 关键字了;当然,如果 你非要用 elseif,一定要在后面跟上条件,这时候可以省去 else 关键字,这样做的优点是让判 断条件更加清楚,缺点是要多敲一点代码。
notion image
如果你的编程思维很清晰的话,使用左侧的代码会更加简洁, 更推荐大家用左侧的代码。
(2)给定一个包含 2 个元素的行向量 a ,请对向量 a 中的元素按照从小到大的顺序排序, 将排序后的结果直接赋值到 a 上,不需要使用新的向量保存排序结果。
此时我们可以省去 else:如果 a  中第一个位置的元素比第二个位置的元素大, 那么就调 换它们的位置并将结果重新赋值给 a ;否则说明不用调换, a 还是原来的,即 if 后面的条件不 成立时,我们什么事情都不用做, else 可以不写。
notion image
下面我们专门介绍一下 if 和 elseif 后面的表达式,在前面的例题中,表达式实际上就是 判断条件, 该判断条件通常是第三章学过的关系运算(例如== 、~= 、>=)和逻辑运算(例如& 、 && 、||、|、~),因此运算结果要么是逻辑值 1(true),要么是逻辑值 0(false)。例如 a(1)>a(2) 、 x>=80 && x<90。事实上, if 和 elseif 后面的表达式也支持其他运算,例如算术运算,其计算 结果可以是一个数值常数,不一定非要是逻辑值 1  或者 0。为什么可以这样? 第三章介绍逻 辑运算时讲过: MATLAB 会将非零数值视为逻辑 1,将数值零视为逻辑 0 进行运算。例如: 3&5 返回逻辑 1 ,-4&0 返回逻辑 0。这里也是类似的: 如果 if 和 elseif 后面表达式的计算结果 为非零数值, 就会被当成逻辑值 1(true); 如果计算结果为数值零, 则会被当成逻辑值 0(false).  当然,我们在实际编程时很少用到这种情况,大家只需要了解背后的原理即可。
notion image
另外有同学可能在 if 或 elseif 后面放上了一个数值向量或者矩阵,这时候只有当这个向 量或者矩阵中的所有元素都是非零元素时,才会被当成逻辑值 1(true)。
notion image
思考题: 修改上面的代码使得:当矩阵 x中至少有一个元素为非零元素时, 就会被当成
逻辑值 1(true)。(答案:将 if 后面的 x 改成 any(x(:))或者 any(any(x))即可)
💀
小技巧: 利用智能缩进整理代码。 俗话说人靠衣装马靠鞍,代码也是这样。在编程时, 优秀的程序员都会注重代码的布局,即代码的缩进、留白等。好的布局会让代码更容易被理 解。细心的同学已经发现了,前面的代码例子中,我在 if、elseif 和 else 下方的语句开头增加 了缩进,这些缩进能让代码整体结构更加清晰,如果不加缩进的话是下面左侧的样子。当你 觉得你的代码看着很不整齐时,你可以选中你的代码,然后按快捷键“ctrl+i ”, 这样MATLAB 会自动帮你整理代码,看起来效果也会好很多。
notion image

(1)if 的嵌套

本小节最后,我们通过一个经典例题来理解 if 的嵌套,所谓 if 的嵌套,是指在 if、elseif 或者 else 下方的语句中又出现了 if 语句(一定要注意: 每个 if 都要有配套的 end)
例题:已知 a 、b 和 c 是三个互不相等的常数,请使用 if 语句找出 a 、b 和 c 三个数的最 大值。(注意,这里是练习条件语句,请不要使用 max 函数直接求最大值)
如果使用原来的思路,我们需要找到各种可能情况并进行多次判断, 流程图和代码如下:
notion image
注意: a>b 且 a>c 涵盖了表中前两种排序的情况; c>b 且 c>a 则涵盖了表中第三种和第四 种排序的情况;如果都不满足则只剩下表中最后两种排序的情况,此时最大值为 b.
notion image
下面我们换一种思路,我们判断的流程图如下:
notion image
从上图可以看出:我们首先判断 a 和 b 的大小关系,然后根据第一次的判断结果分别进 行条件判断,因此出现了嵌套的情况。根据上述流程图可编写下面的代码:
notion image

4.1.2 switch-case-otherwise-end 语句

switch 翻译成中文为开关,switch 语句是另一种实现条件语句的方法,其基本用法如下:
notion image
switch 语句在运行时, 会将开关表达式的值依次和各个 case 后面的表达式的值判断是否 相等,如果相等则为 true ,此时会执行该 case 中相应的语句;如果不相等则为 false,此时会 取下一个 case 后面表达式的值进行比较,直到出现 true 为止。如果所有 case 后面表达式的值 均与开关表达式的值不相等,则执行 otherwise 中对应的语句。
注意: 开关表达式的计算结果必须是一个数值标量或者是一个字符向量/字符串,不能是 向量或者矩阵。若为数值标量,则当 case 后面表达式中的值等于开关表达式的数值标量时为 true ;若为字符向量或字符串, 则当 case  后面表达式中的字符向量/字符串和开关表达式的字 符向量/字符串完全相同时为 true 。下面举两个例子帮助大家理解:
notion image

disp函数(展示需要输出的值)

上面代码中我们用到了 disp  函数(来自单词 display),它可以将文本、数值等显示到 MATLAB 的窗口, disp 语句是否以分号;结尾不会影响结果的输出。
notion image
易错点: 和 if 语句一样, switch 语句必须以 end 结束, 千万不能漏写!
在 if 语句中,有时候我们会不写 elseif 和 else 关键字,而 switch 语句也可以不写 case 和  otherwise 这两个关键字。 另外我们也可以将上面两个例子转换成 if 语句,因此在实际使用中, switch 语句用的频率并不高。下面我们给出转换后的结果:
notion image
注意: 比较两个字符串是否相同可以使用关系运算符==,也可以使用 strcmp 函数; 而比较两个字符 向量是否相同请使用 strcmp 函数。关于文本处理的相关知识, 我们会在下一章中进行系统的讲解。
易错点:下面代码中 n 的值为多少时, MATLAB 会输出成绩合格?
notion image
注意, case 后面 n>=60 是一个判断语句,返回的逻辑值要么为逻辑 1,要么为逻辑 0。如 果 n 等于 0,此时 n>=60 的计算结果为逻辑 0,此时 MATLAB 会认为开关表达式对应的 n 和 case 表达式计算的结果相等,此时会输出成绩合格;当 n 取值为[1,59]时, n>=60 的计算结果 为逻辑 0,和 n 不相等,此时会运行 otherwise 中的语句,即输出成绩不合格;当 n 取值大于 等于 60 时, n>=60 的计算结果为逻辑 1,和 n 也不相等,此时也会运行 otherwise 中的语句, 输出成绩不合格。综上所述,当且仅当 n 等于 0 时才会输出成绩合格,这和我们想要看到的 结果完全不同。那么如何修改代码能使得结果正确呢?答案: 只需要将 switch n  改成 switch true 或者 switch 1 即可。
switch 语句还有另外一种用法,这种用法用到了我们还没正式学过的元胞数组(Cell Array),这里先简单了解下,后面章节会详细介绍元胞数组的知识点。元胞数组和普通的数 值矩阵不同, 元胞数组中的元素可以是不同类型、不同大小的数据。我们之前学过的数值矩 阵中的元素是使用中括号[]括起来的, 而元胞数组中的元素是使用大括号{}括起来的。例如 {25, 15, [6, 3]}是有三个元素的元胞数组, {"abc", [1,2; 3,4]}是有两个元素的元胞数组。
case 后面的表达式可以是一个元胞数组, 如果 switch 后面开关表达式的值和 case 元胞数 组中的至少一个元素相同,则为 true. 下面我们来看一个具体的例子:
notion image
再来看一个输出成绩等级的例子。若 n 表示考试成绩(假设 n 为 0 至 100 的整数,不考 虑输入错误的情况), 其中 90~100  分等级为 A ,80~89  分等级为 B ,70~79  分等级为 C , 60~69 分等级为 D ,60 分以下不及格,请使用 switch 语句输出某一具体分数对应的等级。
notion image
以上是两种不同的思路对应的代码,它们都能解决这个问题。事实上使用 if 语句解决这 个问题更为方便, switch 语句可以转换成对应的 if 语句,大家课后可以自己尝试转换。

Loading...
公告
🎉大学生科技协会(2024)网站试运行🎉
-- 感谢您的支持 --- 科协获:
小平科技创新团队 (青少年科技创新领域国家级最高荣誉,全校唯一)
全国高校百强社团 中国大学生ican物联网创新创业实践教育基地 校十佳社团 “一院一品”智能空间 科技竞赛优秀组织单位
阅读科协简介了解更多吧!