C 生万物 | 分支和循环语句【内含众多经典案例】
看完上一篇文章,我们对 C 语言要学习的一个整体知识框架有了一个了解,接下去,我们将进入分支和循环语句的学习,Are you ready?
@TOC
一、什么是语句?
首先我们来说说什么是语句,在 C 语言中呢,可以将语句分为以下五类
①表达式语句②函数调用语句③控制语句④复合语句⑤空语句
本次我们主要来讲讲==控制语句==,控制语句就是用于控制程序执行的流程,以实现程序的各种结构方式,C 语言是面向过程的,有三种结构方式【顺序结构、选择结构、循环结构】
而上面所说的控制语句在 C 语言中主要是有 9 种,我将其分为以下三类:
第一类:分支语句【if 语句、switch 语句】第二类:循环语句【do while 语句、while 语句、for 语句】第三类:转向语句【break 语句、goto 语句、continue 语句、return 语句】
说了这么多,接下来让我们先进入分支语句的学习
二、分支语句(选择结构)
1、if 语句
单分支与多分支
有关 if 语句的使用我们在初始 C 语言的时候已经讲过,这里不做过多解释,先来看一下这段代码
这里是定义了一个 age 年龄,然后去进行输入,若是输入的年龄 < 18,则打印【未成年】,若是 > 180,那就打印【成年】
具体意思也就是一个判断执行一条语句,满足了这个条件,就进入这个 if 分支执行里面的代码,else 的话就是另一个分支
那有同学问了,难道一个分支只能执行一条语句吗?不可以执行多条?
我们再来看看下面这段代码,可以看到,我在两个 if 分支都加上了{}大括号,这是一个规定,若是你不加上这个大括号,那么这个 if 分支就只会执行一条语句就跳过了
然后我们再来讲一下多分支结构
什么叫多分支结构呢,刚才的话我们是只有 if...else 这两个分支,现在我们的场景不只是【未成年】和【成年】了,而是不同的年龄段为不同的身份,我们来看一下代码
从上述代码可以看出,不同的分支具有不同的结果,而不是像上那样只有 if...else,现在我们输入数据试试看
...
那这个时候有同学问,为什么就可以进入这个分支呢,这个原理是什么?
这就要说到我们的语句执行原理,也就是【真】与【假】
0 表示假,非 0 表示真
那有些学会 C 语言的同学就会想到一个东西【布尔类型】,就是 true/false,这个的话是 C99 里面颁布的,在 C 里面用的还是比较少,C++里面可能多一些,有兴趣的同学可以去研究一下
悬空 else
但是你真的认为 if...else 就那么容易?我们来看一个东西,叫做【悬空 else】,这是一个大家在书写代码是经常会疏漏的地方:star:
首先看下面这段代码,你认为下面会打印出什么内容呢?
首先按照大家的思维理解一下,a 刚开始为 0,所以不会进入第一个分支,而会进入第二个分支,然后打印【haha】,真的是这样吗?我们运行一下试试
可以看到,什么内容都没有被打印,这是为什么呢?
这其实就要讲到我所要说的【悬空 else】,什么是悬空 else 呢,也就是在双层嵌套的 if 语句下,没有加上{}大括号,这个时候 if 分支后的 else 就叫做悬空 else
这个悬空 else 就会产生分歧,到底是和内部的 if 匹配呢,还是和外部的 if 匹配呢?这里也是有规定的,对于悬空的 else,优先和内部的 else 进行一匹配,所以当把我这个代码复制进 VS 编译器时,这个 else 就自动会进行一个缩进,和内部的 if 做一个匹配
所以这就可以印证了为什么没有打印出来任何东西,因为无论是【haha】还是【hehe】,都是处于一个大 if 分支下,而这个大分支的第一层还没有进去,所以程序会直接结束
我们的代码应该改成下面这样
这样的话其实就很清楚了,这个 else 是和内部 if 匹配的,但是其实呢这样也不是很规范,最好是加上{}大括号,才能显得规范一些
if 书写形式的对比
有关 if 语句的书写也是有讲究的,我们一起来看一下
你认为下面两段代码那个是书写规范一些的
答案是第二段,其实它们所要表达的意思都是一样的,这个 condition 就是条件。若是条件成立,则 return x,若是不成立,则 return y
但是为什么说第二段代码更好地,并不是它写得更长一些,而是这个逻辑框架比较清晰,让阅读者看了一目了然
接下去我们再来看另外两段代码,你认为那段代码比较好一些呢
答案也是第二段,那这时候就有同学疑问了【num == 5】是在判断这个 num 值是否为 5,那么把这个 5 放在前面是什么意思呢
这就是说到一个很多程序员都会犯的,也就是把这个判断写成了【num = 5】,变成了一个赋值操作,这其实就会为后期的程序开发买下一个巨大的 Bug,这时你在调 Bug 的时候就会很痛苦,就是找不到哪里有错误,这个时候就去规范我们对于代码的书写
最好是写成【5 == num】,为什么要这样写呢,你看我这个时候将判断等于号改成一个等于号,这个时候编译器就会报错,说【这个表达式必须是可修改的左值】,这其实是正确的,以大家的思维来说,都是讲一个值赋给一个变量,也不会将一个变量给到一个具体的值,也就是【5】这个常量
但程序报出错误的时候程序员就会立马去排错,这个时候也就降低了 Bug 存在的风险
🔥炙手可热的阶段小训练🔥
学完了 if 语句,接下去让我们来做两道练习题巩固一些所学的知识吧
大家可以自己去做一下,这里只给出代码
1、判断一个数是否为奇数
2. 输出 1-100 之间的奇数
2、switch 语句
讲完了一种分支语句,接下来让我们继续学习下一种分支语句,也就是 switch 语句
对于 switch 语句,常常用于多分支的情况,那有同学说,那个多分支不是 if..else 也可以实现吗,那为什么要用这个呢
我们来看看下面这段代码,这是对于星期的一个判断
但是你仔细看,不觉得这样去写这么一个判断很复杂吗,要写这么多 else if,会有些繁琐,接下去我们来学习一下这个【switch 语句】
先来看一些格式
那这个语句项是什么呢?
好,了解了这些后呢,我们使用【switch 语句】来重写一下前面的那个星期判断
今天是星期四,我们来输入 4 运行看看
那这时候有些小伙伴就震惊了,这是什么鬼?我想要的只是星期四而已,但是五、六、天都被输出出来了。这个的话叫做【switch 穿透】,大家不要怕,我们来分析一下:mag:
break
然后我来说一下这是为什么,对于 switch 语句的话,有很多【case】分支,一个语句执行完之后,还是会往下一个语句执行,但是我们希望的是在 case:4 进去,然后打印完了这一句话后便跳出这个判断,不再执行下去了,那这要怎么实现呢?
这时候应该用到一个我们在初始 C 语言里讲到的,叫做 break,到执行到这一个 break 的时候,便会跳出,不会再往下执行了
我们加上这个 break 后试试
可以看到,成功了🎇
但这样子程序还是不完整,我们继续来看看
default 子句
可以看到,我在这个地方输入了一个 8,但是程序什么都没有输出,这是因为 8 没有进入任何一个 switch 分支,所以程序直接结束了。那应该怎么办呀!!!
不要急,这个时候我们应该再增加一个 default 分支,作为默认分支,若是其他 case 子句都没有进入,则会进入这个【default】分支,我们来试试
可以看到,成功了
那这个时候我们换一种思维,当多个条件满足的时候,执行同一个结果,也就是这样的需求
1、输入 1-5,输出的是“weekday”;2、输入 6-7,输出“weekend”
我们来实现一下代码
<font color = "#ff0000">注意事项:break 千万别忘了,很重要,不然会穿透的</font>
📰强大的面试题📰
以下是一道面试题,我们一起来看看
你认为下面会输出多少呢❓
Are you Right? Let's analyze it.
看完我下面这一段实时分析,你就会懂了
三、循环语句
好,讲完了这个分支语句后呢,我们来说一说 C 语言中的循环语句
1、while 循环
看到下面的代码,我们 if 的判断改成 while 就构成了最基本的 while 循环
然后就是我们在初始 C 语言中就讲到过的通过循环来打印 1~10 的数字,在 while 循环内部控制变量的循环条件,若是满足,则一直循环,直到这个循环变量超过边界为止
while 语句中的 break 和 continue
对于 break 和 continue,我们之前在分支判断中也有提到过,那在循环中是怎样的呢,我们来看一下
你认为下面这段代码会打印什么内容。break 的话停止后期的所有的循环,直接终止循环
可以看到,因为当 i 循环到 5 的时候,遇到了 break,因此跳出了整个 while 循环,不会执行下面的 printf 打印语句以及 i++了,所以只会打印到 4
然后我们再来看看 continue
对于 continue 的话,是终止本次循环,强制进入下一次循环
可以看到这个光标的值,停留在 4 的后面不动了,这是为什么呢?
我们来分析一下
可以看到,这其实是一个死循环,当 i 加到 5 的时候,由于进入了 continue,所以 i 不会进行一个递增,继而导致了这个死循环
那这个代码应该怎么改才不会死循环呢?对,就是把这个 i++放到 if 判断的前面
看完了【break】和【continue】,接下去我们来总结一下
<font color = "#ff0000">continue - >>某种条件成立时跳过后面的代码</font><font color = "#ff0000">break - >>某种条件成立时整个循环不执行</font>
getchar()的巧妙运用
讲到 while 循环,我们来说说【getchar()】这个库函数的使用
上述图是运行结果以及cplusplus的资料
对于 getchar()的话是对键盘读入一个字符,然后可以通过 putchar()输出。要注意到,这个 getchar()的返回值是 int,这个我们下面会讲到
这个时候有同学问了,这个 getchar()和 while 循环有什么关系呢?
我们来看看下面这段代码
从运行结果可以看到,使用 while 循环,每当我们输入一行数据,知道按下回车,putchar()会将这一行数据原封不动地打印出来
这里的【EOF】指的就是【End Of File】文件末尾的,循环的意思是==当这个输入没有到达文件末尾时,getchar()就会从键盘上不断地去读取数据,直到文件末尾即要换行为止==
那这个时候又有同学说,这个 getchar()很厉害呀,竟然可以读一串数据
但其实这个 getchar()的使用是存在缺陷的,我们一起来看看
这是一段确认密码的程序
可以看到,我在输入完密码然后换行后,但是还没有去确认密码,但是程序直接结束了,说【确认失败】,这是为什么呢?这个 getchar()到底有没有执行?
我们来看一下==计算机内部缓冲区读取数据的原理==
从这张原理图可以很清楚地看出,scanf 会从键盘上读取一些你输入的数据,但你不输入的时候,它就一直等,一直等,直等到你输入为止。
但是这个 scanf 不会直接去取你这个键盘上输入的数据,在计算机中呢,是存在一个输入缓冲区的,但我们把这个数据从键盘上输入进去的时候,会先进入缓冲区,当我这个 123456 输入进去后,为了让数据进入到缓冲区,我还敲了一个回车,表示这个输入结束
然后 scanf 进来到缓冲区看了,有没有数据我可以读的,这时候它看到有数据,它就读,直到读到\n 为止。然后将这个数据给到 password 作为密码;此时 getchar()也来读数据了,这个 getchar()的工作原理其实和 scanf()是一样的,就看缓冲区里有没有东西,然后看到,哟,有个【\n】,于是读取了这个数据,把它放到 ch 里面去了,那接着就去判断这个 ch 为‘Y’吗,很明显不为‘Y’,所以就进入了 else,打印了【确认失败】,==这就是编译器没有等我们输入确认密码就直接结束程序的原因==
你明白了吗?
2、for 循环
语法明细
看完了 while 循环,接下去我们来看看 for 循环,对于 for 循环大家一定不陌生,它是使用最多的循环语句
那有同学问了,我们既然已经有这个 while 循环了,为什么还要 for 循环呢,让我们先来看一下 for 循环的语法
表达式 1 为初始化部分,用于初始化循环变量的
表达式 2 为条件判断部分,用于判断循环时候终止
表达式 3 为调整部分,用于循环条件的调整
可以看到,for 循环不像 while 循环那样,将三个表达式分散在整个程序的各处,对于 for 循环的话都是放在这一个小括号里进行,每个表达式使用分号进行分隔
就像我们这里去打印 1-10 的数字,使用 for 循环的话就会很清晰直观,代码也比较简练
可以看到,一样是可以打印出来
for 循环中的 break 和 continue
在 while 循环中,我们有详细讲到过 break 和 continue,但是在 for 循环中是如何使用的呢?我们一起来看看
首先来看 break,很清晰直观,循环从 1 开始,循环的边界是到 10,i++进行一个递增,也就是 i 加到 11 的时候会跳出这个 for 循环,然后看循环体内部,当循环进入时若判断这个【i == 5】时,则执行 break 语句跳出循环;若没有到达 5,则会打印这个 i
然后我们再来看 continue
从运行结果可以看到,为什么这次在 for 循环中直接打印会输出 1234,然后 678910 呢,而不是像 while 循环那样在 4 的地方终止,然后死循环,这就是因为这个 i++是 for 循环每次进入的时候就会执行,就和我们在 while 循环中把 i++放到上面来是一个道理
对于这点,我们在下一个模块来详细讲一下==for 的执行流程==
执行流程解释
但是初次接触这个 for 循环的同学一定对这个循环的执行流程有所困惑,因为对于 while 循环的话,代码虽然是写得比较散,但是却很好理解,for 循环就会显得堆在一起的感觉
我们一起来看一下这个执行流程到底是怎样的
从上图可以看出循环进入时,首先执行第一个表达式,也就是初始化部分,然后在进行条件判断,若是不为 0,则继续执行下面的循环体语句,执行好后又来到表达式 3【expr3】,调整循环变量后继续
若是这个条件判断依旧【! = 0】,此时会继续进入循环,然后直到条件循环为 0 为止,才会结束循环
然后可以看到图中还有这个【continue】和【break】,对于 continue 来说呢,就是跳出本次的循环,不执行下面的循环体语句了,直接回到循环体开头对循环变量进行调整;而对于 break 呢,可以看到,直接来到了这个【expr1 == 0】这条支路,说明会直接结束循环的运行
📕多学几招📕
接下去给大家讲讲在 for 循环使用时的一些注意事项和一些技巧
你认为下面这段代码的执行结果是什么
可以看到,【满屏的 666】
如果大家觉得我讲到好的话,在弹幕上扣一波【666】,不过 CSDN 的文章里没有这个功能,但是你可以在评论区扣(doge)
好,言归正传,为什么这个直接结果会都是 666,但是你自己观察可以发现,第一个打印的是 1,这个时候你就可以根据我上面的 for 循环流程图,将这个
3、do...while 循环
讲完了 while、for,接下去让我们来看看 do...while 循环,这也是循环语句的一种,只是在各个应用场景中没有 while 和 for 来得广泛
语法介绍及案例分析
首先来看一下它的语法格式,和 while 循环很类似
然后再来说一下其特点,因为 do...while 循环在执行到时一定会进入循环体,然后再进行一个判断看看是否要继续执行。但是对于大多数使用循环的场景,都是需要先进行一个判断,然后在执行一个循环,所以这就让 do...while 的使用场景变得十分有限
我们先来一个具体的小案例
业务逻辑是需要使用 do...while 循环去打印 1~10 的数字,这个逻辑的话我们在 while 循环和 for 循环都有实现过
刚才说过,对于 do...while 循环,遍历到的时候会直接进入循环体,这里会打印 i 然后 i++,判断 i【i == 2】,所以继续执行循环,直到这个 i 加到 11 的时候便不再进入循环,结束程序的运行
do...while 中的 break 和 continue
对于 break 和 continue 这两个关键字,也是从本文的开始就一直陪伴我们,让我们到 do...while 中来看看它们要如何使用
break
可以看到,其实和 while 循环是相似的,也是当 i 为 5 的时候终止循环
continue
可以看到,对于 continue 也是一样,若是这个 i++在 continue 语句的后面,则在 continue 语句执行到的时候,就会强制进入下一循环,那么这个 i 便一直会是 5 了,始终不会被打印出来,就造成了死循环
四、实战小训练
1、 计算 n 的阶乘
首先第一题比较简单,计算一个 n 的阶乘,那只要定义一个变量去存放这个阶乘的结果,然后通过循环去遍历即可
这里要注意,ret 初始要置为 1,否则在任何数和 0 相乘必定为 0
2、 计算 1!+2!+3!+……+10!
第二小题又是一道计算阶乘的题,不过这题计算的阶乘不是单个的,而是计算一个累加阶乘的和,我们一起来看看
假设我们是要计算 1! + 2! + 3!,数字小一些。首先来分析一下思路,因为要计算的数字只到 3,所以我们需要一个外层循环从 1 遍历到 3,表示求解的是这 3 个数的阶乘
然后内层循环就是每一个数的阶乘求解,从 1 遍历到这个数即可,然后使用一个累乘变量存放起来。在计算完每一个数字的阶乘后,我们就需要去累加这些阶乘的和,所以还需要定义一个 sum 变量去存放这个和,最后 sum 变量就是我们所要求的结果
正确答案应该是 1 + 2 + 6 = 9,我们通过 VS 来跑一下看看
可以看到,sum 的结果并不是 9,多了。这是为什么呢?
这里其实就是很多通过都会犯的错误,因为我们是在求解不同数字的阶乘,但是使用的累乘变量却是同一个 ret,所以下一个数字需要计算的时候,这个 ret 还是上一次数字累乘后的结果,这就导致了阶乘计算的不准确,所以结果也会不同
具体的错误大家可以自己去 DeBug 试一试,是这个 3!在计算的时候多乘了一个 2!遗留下来的 2,所以使得 3!= 12,多了 6,因此最终结果也就多了 6
应该加上这句话才对,在每一次更新需要求阶乘的数时,都将这个累乘变量 ret 重置
其实还有一种更加方便的方法,使用一次循环就可以把结果计算出来,具体的演示过程已经给出,大家自己分析一下即可
3、 在一个有序数组中查找具体的某个数字 n【讲解二分查找】
然后就是这道在个有序数组中查找具体的某个数字 n
那有同学一看到要在一个数组中查找一个数字,就想到去遍历这个数组,这个逻辑是对的,但是不够巧妙,我们需要更加巧妙一点的办法去解决这个问题
这里介绍一个查找方法,叫做==二分查找==,什么叫二分查找呢?就是在一个数组的左右两段各定义一个指针,然后取它们的中间值,然后将你要查找的数字与这个中间值进行比较,若是比中间值要小,那么就去除掉后面那一部分区间,只需要找前面就可以了,若是比中间值要大,则去除掉前面那一部分区间,找后面。将这个逻辑放到一个循环中,不断地去更新中间值,然后做比较,最后左右两段的指针会重合,表示这个区间快要结束了,若是当左指针大于右指针时,也就意味着已经查找到所需要的元素或者是没有找到,此时便要退出循环进行一个相对的打印说明
讲完了这一块的逻辑后,我们来看一下具体的代码
具体的讲解我就不说了,你们可看我的另一篇文章,做了详细介绍二分法与折半插入排序
4、编写代码,演示多个字符从两端移动,向中间汇聚【微信手机端看不到视频】
然后我们来玩一个很有趣的东西,将多个字符从两端移动,向中间汇聚
我们来看一下,演示多个字符从两端移动向中间汇聚,我们需要实现一个覆盖的效果,比如我下面定义了两个数组,我们最终需要打印出来的效果是第一个数组的内容,但是在打印过程中我们需要打印第一个数组,然后也是通过两段左右指针去进行一个覆盖的效果
首先是对于左右指针的初始化,左指针就是 0,但是对于右指针的话,这里取不到它的末尾值,所以这个时候我们需要使用到 strlen()这个库函数去求解数组 1 的长度,然后-1 就是右指针的位置
我们也是将这个逻辑放到一个循环中,然后把第一个数组的内容通过两个左右指针赋给第二个数组,然后这两个指针不断往中间移动,直至左指针大于右指针为止
这里为了让其慢慢地显示出来,呈现一个动画的效果,又使用到了一个库函数,也就是 Sleep()睡眠函数,这个函数还是蛮有意思的,参数的话你需要传入毫秒值,比如说 1s 执行一个就传入 1000,0.5 执行一下就传入 500。还有这个函数需要引入头文件【#include <Windows.h>】,大家记得加上哦
然后我们通过运行结果来看看这个效果是怎样
[video(video-JUqwkuMS-1666671841689)(type-csdn)(url-https://live.csdn.net/v/embed/247980)(image-https://video-community.csdnimg.cn/vod-84deb4/eb50040f2835448ba6dad09d0382ed32/snapshots/ca1a0d18a916465fb39ff11274cfe2e3-00001.jpg?auth_key=4820212508-0-0-ce3c6bccf52d912ef9a3f83b65b96cfc)(title-QQ录屏 20221024174502)]
为了让其在一行打印,不需要一行行地打印,我们可以使用这样一个命令
但是这个 system()函数要加上头文件【#include <stdlib.h>】,大家不要忘了。我们加上这条语句后再来看看运行效果是怎样的
[video(video-Q24mZ0io-1666671888836)(type-csdn)(url-https://live.csdn.net/v/embed/247982)(image-https://video-community.csdnimg.cn/vod-84deb4/34e4bd79021942348ed09b3b0de4a343/snapshots/7c8bb45bbd40414c9649054fe16d1990-00001.jpg?auth_key=4820217046-0-0-2b87b46aaedb5f32dd4773bfb9c60369)(title-两端移动)]
5、密码校验
这道题的话就是我们输入一串字符,然后通过与正确密码进行一个比较,看看是否相同,若是相同,则直接 break 跳出循环,若是不同则继续输入,但是机会只有 3 次,用完之后便跳出循环不允许再输入了
实现逻辑并不难,你可以先自己写写看,检验一下自己学得怎么样,然后再来和我的程序进行一个比较
这里要注意的一个地方是有挂字符串比较的问题,我们不可以直接使用【==】去进行一个比较,而是要通过一个字符串的库函数 strcmp 进行比较。有关其返回值的问题,我们通过Cplusplus来看看
也就是当这个第一个字符串的首字母大于第二个字符串的首字母时,就返回大于 0 的数字,小于 0 则是相反,若是两个字符串相同,则返回 0。这里比较的是 ASCLL 码值的大小
6、猜数字游戏【经典】
好,接下来我们来玩一个 C 语言中很经典的游戏,叫做==猜数字==
首先我们来实现一个整体的逻辑,也就是当你 input 输入的时候,通过我们上面学习的 switch 语句进行一个分支的判断,是要继续猜数字还是退出游戏
一起先来看一下代码,首先你要有一个菜单供玩家去选择
可以看到,整体的逻辑已经实现了让你按下【1】的时候,会实现一个猜数字的功能,若是一直按 1,则可以一直猜数字,直到你按下 0 为止就可以
接下我们就要实现猜数字的内部游戏逻辑,这个逻辑其实也是非常简单,通过系统随机生成一个数字,然后你在屏幕上去输入这个数字去猜,若是比这个数大,则提示数字大了;若是比这个数小,则提示数字小了,然后直到你刚好猜中为止
首先我们来讲讲这个随机数是如何生成的
这就要用到 C 语言中的一个函数叫做 rand(),你可以在 Cplusplus 中找找看这个,可以看到,这是一个生成随机数的函数,参数是空参。它的范围是【0~32767】
但是我们要实现的是随机生成一个 1~100 之间的数字,这个时候你就需要在这个函数后面对 100 进行取余即可,就是【0-99】之间的数字,再在后面加上一个 1,就是【1-100】
我们通过 printf 来打印一下,看看系统生成了那些随机数
可以看到,在一次游戏的过程中,数字是不一样的,但是在第二次又打开时,确实和第一次相等的随机数,这就出现了问题,你要想若是玩家碰到了这样的情况,每次都是相同的数字,它还会继续玩下去吗,当然这只是打个比方:camera:
那我们要怎么去解决这个问题呢?这个时候我们就要使用到一个 C 语言中的另一个函数叫做随机种子 srand(),我们通过 Cplusplus 再来看看
但是呢,光有这个函数还不够,一般还要再配合使用一个时间戳函数 time()
直接让你看看具体是如何使用的
我们来分析一下,首先看到这个 time()函数,里面的参数设置了 NULL 为空,然后前面为什么要强转成(unsigned int)呢,因为这个 srand()函数的参数类型就是(unsigned int),所以需要进行一个强转
这句话大家要记得加在游戏循环的外面,因为这个随机种子最好是不要多次使用,用一次就可以了,多次使用的话会导致一些错误,所以将其放在 main 函数开头的位置即可
还有一点不要忘了,这个 time()函数是要包含头文件的【#include <time.h>】
我们加上这句话后再来看看两次打开游戏的运行结果是怎么样的
可以看到,产生了这个随机的效果
好,后面我们就要来真正地实现这个猜数字的逻辑了,直接让你看看代码就会了:wind_chime:
对了,记得把这个随机生成的打印数字去掉,不然你就看到答案了
我们来看看运行结果。可以看到,整体的整个简易逻辑已经得到了实现,你可以自己到编译器中试试看:computer:
五、goto 语句【了解即可】
接下去我们来说说 goto 语句,对于 goto 语句,开头有提到过,是属于转向语句的一种,其余的还有 break、continue 和 return 语句上面在讲分支和循环语句的时候都已经有涉及到了
我们直接来看一个小案例,这里是在一个输出语句 printf 的后面加了一个 goto 语句,然后执行这个 goto 语句的话会跳到输出语句的前面, 然后继续执行下面的代码,这里要注意,【跳转的地方变量后面是要使用冒号的!!!】
然后我们来看一下运行结果
可以看到,上面是输出了很多的【hehe】,表明这已经进入了一个死循环了,当然这只是一个小案例,让你了解一下 goto 语句的执行流程,平常写代码可不能这么去写
然后我们再来看一个,下面这段代码的意思是在打印完一个【hehe】语句的时候,执行一个 goto 语句,然后会直接跳转到下一个【heihei】语句,并不会执行【haha】语句
真的会是这样吗,让我们一起来看一下结果
可以看到,【haha】语句并没有被执行,这也印证了我们的猜想
以上就是 goto 语句的一些基本用法就,大家了解一下即可,不用去过度深究,因为对于 goto 语句的话其实在某些地方使用是不太好的,因为程序是一行行执行的,若是进行了一个跳转的话就会导致整个程序的逻辑混乱,所以还是不太建议大家去使用这个语句
一般的 goto 语句真正适合运用的地方其实是==多层嵌套循环的地方==,可以节省 break 子句的频繁使用,只需要一次 goto 即可跳出循环。
虽然 goto 语句不为广为使用,但是上面说过了,在某些场合下还是可以派的上用场的,下面我们来说一个使用 goto 语句的经典案例
下面这段程序很有趣,是网上的一个段子改编的,使用 system()函数调用一个 60s 后关机程序,然后输入【***】,若是和它要你输入的内容一直,就取消关机程序,若是不一致,则使用 goto 语句继续跳转回来,直到你输入的内容是它要的内容为止
哈哈,看了这个输入内容确实是很有趣,大家下去可以自己试试看,是不是真的会关机【记得保存包文件哦 doge】
不过这段逻辑还可以使用 while 循环实现,然后符合规则的话就 break 跳出即可
六、总结与提炼
在本文中,我们学习了分支和循环语句,在分支语句中,我们学到了【if...else】和【if...elseif】分支判断,以及 switch 语句中 case 和 default 子句的使用。在循环语句中,我们学到了 while 循环、for 循环、以及 do...while 循环,并且观察了 break 和 continue 子句在上述分支和循环子句中的具体使用和注意事项
后期阶段,我们还通过了 5 个实战小训练,对这些知识点有了一个很好的回顾和消化,让大家对分支和循环语句的了解更加深刻
在最后,我们又介绍了一个跳转语句 goto,不过除了在多循环嵌套的情况下其他地方不建议使用
以上就是本文所要讲的所有内容,感谢您的观看,如有疑问请于评论区留言或私信我:rose:
版权声明: 本文为 InfoQ 作者【Fire_Shield】的原创文章。
原文链接:【http://xie.infoq.cn/article/ed9e275ac3c0e73bb1c158727】。文章转载请联系作者。
评论