循环结构

循环即重复执行某件事情。例如 “敲门直到门打开为止”、“鼓掌一百次” 。。。

有时,某段相同的代码逻辑我们需要重复做很多次,为了不过多写重复的代码,我们需要使用循环。

有时,要重复执行的次数不是固定的,必须使用循环。

在思考和循环有关的问题时,要想清楚循环里面要重复做的是什么事

循环常用的写法有三种,不管是哪种都能实现循环的逻辑,根据情况选择更简单的写法即可:

1.变量自增自减

有时我们需要让变量进行增加 1 或者减少 1 的操作,可以用复合运算符 +=-= 实现,也可以用自增运算符 ++ 和 自减运算符 -- 更简单的实现。

自增/自减运算符可以放在变量前面或后面,在变量名前称为前缀,例如 ++i ;在变量名后称为后缀,例如 i++ 。在单独使用时,两者无需特别区分,但如果在表达式中包含了其中一部分,则需要注意,参考下面的例子:

int i = 100;

int op1 = i++;  // 先执行 op1 = i,再执行 i = i + 1;
// 执行结束后, op1 = 100,i = 101
int op2 = ++i;  // 先执行 i = i + 1,再执行 op2 = i;
// 执行结束后,op2 = 102,i = 102
int op3 = i--;  // 先执行 op3 = i,再执行 i = i - 1;
// 执行结束后,op3 = 102,i = 101
int op4 = --i;  // 先执行 i = i - 1,再执行 op4 = i;
// 执行结束后,op4 = 100,i = 100

2.while 循环

格式为:

while (条件表达式) {
	循环体;
}

执行顺序:

image.png

一般为了保证循环的正常执行和结束,在循环体中一定会有代码来 改变和条件表达式有关的变量的值,除此之外,循环体里可以是任何符合语法的代码。

示例,输出 1~n 的所有整数,如何把这个功能转换为重复执行的流程:

假设有一个变量 i 初始为 1,那么:

  1. 输出这个变量 i
  2. 将这个变量的值加 1

可以发现,若第一次执行这段代码,会输出 1i 变为 2 ;第二次执行,输出 2i 变为 3 ,以此类推。。。所以,如果想输出 1~n 的所有数字,就应该重复执行到 i 大于 n 为止,反过来说,当 i <= n 时,就要继续执行这段代码,所以可得:

int i = 1, n;
cin >> n;
while (i <= n) {
	cout << i << '\n';
	i++;
}

格式为:

do {
	循环体;
} while (条件表达式);

执行顺序:

image.png

其与 while 循环的区别在于,do...while 循环是先执行循环体中的代码,再判断条件表达式是否成立。

例如这段代码:

int i = 3, n = 2;

do {
	cout << i << '\n';
	i++;
} while (i <= n);

循环在输出一次 3 后结束。

4.for 循环

格式为:

for (初始化; 条件表达式; 更新) {
	循环体;
}

执行顺序:

image.png

例如,for 循环来实现输出 1~n 的数字,示例代码:

int n;
cin >> n;
for (int i=1; i<=n; i++) {
	cout << i << '\n';
}

for 语句括号里的三个部分,任何一个部分都可以省略;其中,如果省略了条件表达式,相当于判断条件永远为 true

5.课上例题

循环输出 1~n 的数字

输出 1~n 中的奇数

求 1~n 的总和

求 1~n 的阶乘

求 1~n 中的好数之和

break与continue语句

使用这两个语句可以让循环的逻辑更清晰,

1.break 语句

break 语句的作用是退出循环,假设现在有这样的功能:

输入一个正整数 n,求 1~n 的总和,但如果在求的过程中,总和超过了 100,则直接输出总和并结束循环。

利用 break 可以做到:

int n, sum = 0;
cin >> n;
for (int i=1; i<=n; i++) {
	sum += i;
	if (sum > 100) {
		break;
	}
}

cout << sum << '\n';

当然,其实不用 break 也可以做到,即这样写:

int n, sum = 0;
cin >> n;
for (int i=1; i<=n and sum <= 100; i++) {
	sum += i;
}

cout << sum << '\n';

这样看起来代码少,但是逻辑阅读起来其实并不很清晰,一般来说,我们通过循环来【枚举】,通过 break 来实现【到何时为止】这样的逻辑。

2.continue 语句

continue 语句的作用是跳过这一次循环里,循环体的余下部分,直接开始下一次循环判断。

例如,现在想输出所有 1~n 当中不能被 3 整除的数字,并且每个数字要重复输出 5 次,代码可以这样写:

int n;
cin >> n;
for (int i=1; i<=n; i++) {
	if (i % 3 != 0) {  // 不能被3整除
		for (int j=1; j<=5; j++) {
			cout << i << " ";
		}
		cout << '\n';
	}
}

如果用 continue 来做,可以这样写:

int n;
cin >> n;
for (int i=1; i<=n; i++) {
	if (i % 3 == 0) {  // 能被3整除,就跳过本次循环的后续语句
		continue;
	}
	for (int j=1; j<=5; j++) {
		cout << i << " ";
	}
	cout << '\n';
}

对比可以发现,减少了一层嵌套的括号,代码会更清晰。

3.课上例题

寻找777

排队问题

排队问题2

乘方计算

人口增长

练习

分苹果

一尺之棰

球弹跳高度的计算

乘方

国王的金币

余数相同问题

小W卖货

搬砖人搬砖魂

计算分数表达式的值

角谷猜想