欢迎光临散文网 会员登陆 & 注册

第 16 讲:程序结构(二):循环结构

2021-03-31 08:38 作者:SunnieShine  | 我要投稿

如果我们重复执行特别多相同或相似的操作,如果使用一句一句代码来书写的话,显然是会使得程序臃肿的,而且还麻烦。于是,循环结构就诞生了。

C# 里提供了四种循环结构语句:while 语句、do-while 语句、for 循环和 foreach 循环。下面我们挨个进行介绍。

foreach 循环我们不在这里介绍。因为它需要用到一个新的东西,叫做数组(Array)。所以本节内容我们只讲前面三种循环语句。

Part 1 while 语句

最基础的语句就是 while 语句。while 语句的格式是这样的:

if 写法基本上是一样的,只是 if 改成了 while。比如说,我们要计算从 1 到 100 的和,代码可以这么写:

whileif 的格式完全就只有关键字不一样,其它地方写法都是一样的。它的执行逻辑是这样的:我们首先从 i <= 100 这里开始判断。由于 i 从 1 开始,所以条件必然是成立的。按照条件要求,大括号里的代码就会执行一遍。因此,sum = sum + ii++ 都会执行一次。执行完毕后,会返回到 while 循环的条件(i <= 100)处再次判断条件。由于 i 此时执行了一次 i++ 变成了 2,所以和原来的数据不一样了。但是,2 依旧是满足 i <= 100 的条件的,于是又会进来执行 sum = sum + ii++。在反复执行到 i 超过 100 的时候,while 循环就不再执行了,直接到第 8 行,输出 sum 的结果。

如果你是初学编程的话,可能看起来会有点吃力。但是从逻辑上来说,你可以知道一点。循环体(就是大括号这一坨代码)里,i 始终是一个单位一个单位地在增大。那么,从 i 最开始的 1 开始,就会在内部反复执行到 101 才结束。为什么是 101 呢?因为条件 i <= 100 是到 100 都满足的,因此第一个不满足的数值应该是 101 才对。

另外,虽然到 101 才是对的,但内部循环体始终执行的次数是 100 次,即 i 是 1 的时候执行一次,是 2 的时候执行一次,3 的时候执行一次……直到 i 是 100 的时候,还会执行一次。这一共是 100 次(特别需要注意的是,从 1 到 100 是一百次,不是 99 次)。

最后,每一次执行,都会执行 sum = sum + i 这个规程,而每次都是记录了 i 当前的最新数据(1、2、3、4 等等),因此 sum 最终的结果一定是累计从 1 到 100 的总和。所以程序是没有问题的。

下面我们回头来看。sum = sum + i 可以改成 sum += i,而 i++ 写在前面那个语句 sum = sum + i 之后,且这个语句里也用到了 i,所以我们还可以把 i++ 合并到前面那个语句里。所以,循环体甚至可以简化成这样:

当然了。大括号只有这么一个语句的话,按照道理是可以不写大括号的。所以,第 3、5 行的大括号是可以不要的。

这样代码就会少很多。

思考一个问题。请问,如下的代码依旧是计算从 1 到 100 的和。请问这样写代码是否正确:

请说明原因。

Part 2 do-while 语句

由于有些时候,我们没有必要让用户最开始就判断数据是否需要循环,因此 C# 提供了一种后置条件的循环语句:do-while。它的格式有点别扭:

do 关键字就是为了起到一个占位的作用,用来框定循环体范围,没别的用。这种循环不论如何都会先执行一遍。执行完毕后,再来看条件是不是成立。注意,这里的条件写的是 ++i <= 100,所以注意先执行 ++i,然后才是条件判断。

可以看出,++i 这个语法格式是比较重要的。如果没有它的话,我们不论如何都无法做到在循环体执行完毕后立刻先让 i 增大一个单位,然后才是判断循环。不过确实,你也可以把 i++ 写进循环里,不过逻辑嘛,你就自己理解了。

顺带一提,循环体只有一个语句的时候,大括号是可以省略的。

你可以这么写。当然,再浪一点的话,你还可以这么写:

只是一定要注意,do-while 是一个整体形式的语句。因此在最后需要加分号。在之前的 ifswitchwhile 这些东西的最后都不加分号,这是因为它们要么本身就已经以分号的语句结尾,要么大括号结尾。而 do-while 语句的特殊性,最后一个地方写的是条件表达式,因此一定要加分号。

Part 3 for 语句

最舒服的语法还得是 for。前面两种循环我们都大概看了一下,应该没有大问题。不过 for 循环语句可能难度偏大一些,因为它的写法很灵活。

3-1 标准格式

如果我们改写一下从 1 到 100 的和,用 for 循环的话,我们可以这么写:

for 的格式是这样的:

这里就需要稍微注意一下,for 后面的小括号里是用分号分隔的每一组数据。从语义上理解的话,我们可以认为 for 循环是一种迭代循环。所谓的迭代,就是让一个实体对象作为基础参考,一直追踪它自身变化的过程。每次循环完毕后,这个东西都会变化,然后将变化后的结果继续带入下一次的运算过程。

比如说,我们完全可以只看 i 来找出变化过程。i 是从 1 到 100,一次增大一个单位,因此在小括号里我们写的是 int i = 1; i <= 100; i++。最左边的是初始赋值语句,表示 i 从多少开始;中间这个写变量应该在什么范围区间里不断循环。显然这里我们需要写的是 i <= 100,因为这样才能表示 i 在 100 以内都要反复执行循环。最后一个部分写的是 i++,这正好对应了循环体执行完毕后自动增大一个单位的过程。最后,在循环体里,我们只需要关心 sum 的变化即可。这就是 for 循环的语义理解方式。

3-2 缺省迭代

在循环的时候,我们有时候不一定非得要写一些东西。如果我们需要把初始赋值提出来的话,我们可以这么搞:

如果我们想把增量写到循环体里,可以这么搞:

你甚至可以省略两部分:

你还可以玩骚操作,把循环体当增量写进增量里面去:

大括号都没东西了,干脆改成空语句(Null Statement)吧。

空语句就是一个以分号结尾的语句,这个语句里啥都不写,就写成一个分号 ;。这种语句本来是毫无意义的写法,但是为了保证 for 循环这种循环体完整,我们追加一个空语句来表示和限定 for 的执行范围,保证编译器分析代码的时候不出问题。

3-3 复合迭代

在迭代的过程之中,for 循环还允许我们使用多个变量同时迭代。

比如这个例子里,ij 变量同时声明到循环的小括号里。这个表示 ij 同时赋初始数值;而后面的 i++j += 2 是同时充当增量。在执行过程之中,i++ 先执行,然后就是 j += 2

从这个角度来说,for 循环允许我们添加多个变量的迭代过程,因此 C# 使用的是逗号分隔每一个迭代变量;而每一个部分使用分号分隔。

Part 4 死循环

既然 if 可以写永真条件,那么 while 这些循环呢?是的,我们完全可以这么做。

这种条件是 true 的永真式,我们就把这种循环叫做死循环(Dead Loop)。死循环是永远都不会自动退出的,只要它从上到下执行的时候遇到这种死循环了,就不会主动退出来。

我们不提倡也不支持任何没有意义的死循环,因为它只能卡死程序,没别的用处。

Part 5 特殊循环控制语句

为了帮助辅助使用循环语句,我们可以在循环里插入一些特殊的语句,来灵活控制执行过程。

5-1 break 语句

这个单词是不是很熟悉?是的,就是之前 switch 语句最后跟的那个东西。它还有一个作用就是使得循环体的代码不再执行,自动跳出循环。

for 循环里嵌入了一个 if 语句,这表示每一次循环体开始执行的时候,都执行判断,是否 i % 3 == 0。由于 i 从 1 到 5,因此会在判断之后,执行输出语句。一旦遇到 i % 3 == 0 条件成立的时候,就会自动执行 break 语句,整个 for 循环后面的代码都不再执行了,直接跳出整个循环。

5-2 continue 语句

break 语句相反,continue 语句是反过来的。它表示直接跳转到循环条件判断或增量的地方去执行。我们拿两个例子来举例:

一旦遇到 continue 语句,就会自动跳转到循环的条件判断,或者是增量处。比如说 while 循环,遇到 continue 语句的时候,就会自动跳转到 ++i <= 100;而后者 for 循环,遇到 continue 的时候,就会自动跳转到 i++

5-3 死循环里使用循环控制语句

在完成了前面的内容的学习之后,我们来看看死循环怎么嵌套这种东西。

思考一下,这样写能不能完成求 1 到 100 的和的任务。

这里条件写的是 true。实际上 for 循环里的条件是可以不写的,默认是 truefor (; ; i++) 就等价于 for (; true; i++),但 whiledo-while 不行。


第 16 讲:程序结构(二):循环结构的评论 (共 条)

分享到微博请遵守国家法律