唐巧的博客

CSPJ 教学思考:for 循环

字数统计: 2.4k阅读时长: 9 min
2024/11/07

背景和问题

小学生在学习编程的时候,像变量,赋值,输入,输出,分支这些逻辑相对容易理解。因为这与人类真实世界的很多行为相似,所以学生会很容易吸收。具体来说:

  • 变量其实就是我们平时取的“名字”或者“外号”,用于指代一种特定物品。
  • 赋值相当于为这种特定物品指定一种属性值,像是苹果的重量,价格一样。
  • 输入和输出在很多电子产品中都有接触,孩子现在很小就接触手机,非常容易理解键盘就是一种输入,屏幕显示就是一种输出。
  • 分支就是我们自然语言中的“如果…就”,非常容易类比。

但是,for 循环由于其很难与现实世界“类比”,所以成为小学生学习编程的第一个障碍。

如何理解 for 循环,并且灵活运用 for 循环,成为一个教学难点。

教学思考

我在教学 for 循环的时候发现,如果我们用尽量渐进式的方式,让孩子刚开始接触到的 for 循环与现实世界数学中的数列一一对应。然后,再一步一步拔高难度,随着难度提高,最终 for 循环可以实现求解“非波拉切数列”以及“小数点后 10000 位”这类已经高度变型的题目。

因为每一步的难度提升梯度很小,所以学生虽然找不到现实世界类比,但终于还是比较容易理解整个渐进变化的过程。

这就类似于我们学立体几何前先学平面几何,学平面几何前先学点线面一样。从微小的简单事物开始,我们最终可以创造整个世界。

以下是我对 for 循环的具体教学拆解。

教学拆解

1、用 for 循环输出数列

输出从 1-N 的等差数列是使用 for 循环最基础形式。我们先用这个引入,让孩子先初步了解 for 循环的三段形式。

for 循环的三段式其实对初学者来说还是有点绕,借此环节把 for 的基本格式熟悉。

示例代码:

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

2、用 for 循环输出 1-N 的和

累加器的写法对于初学者来说是一个小障碍,但是累加器与 for 循环的结合使用在之后的变化很常见,所以我们在这个阶段把累加器引入,帮助孩子建立累加器的使用习惯。

示例代码:

int sum = 0;
cin >> n;
for (int i = 1; i <= n; ++i) {
sum += i;
}
cout << sum << endl;

注:对于不习惯 += 的学生,也可以刚开始用 sum = sum + i来教学,减少学生的陌生感。

此题对应的线上练习是:《2016:【例4.1】for循环求和》

此题也可以进一步变化为:分别求奇数和、偶数和。让学生学会在 for 里面嵌入 if 表达式。

3、用 for 循环输出 1-N 的和的平均值

平均值的计算涉及整除的概念,需要在除之前将被除数转化为小数,同时需要用 iomanip 头文件中的函数来控制输出格式,这一编程技巧正好在这一步引入,让学生逐步熟悉对输出的控制。

示例代码:

#include <iomanip>
// 此处省略若干行

int sum = 0;
cin >> n;
for (int i = 1; i <= n; ++i) {
sum += i;
}
cout << fixed << setprecision(6) << double(sum)/n << endl;

此题对应的线上练习是:《1060:均值》

4、输入 N,接着输入 N 个数求和

大部分学生以为 for 循环是 for 循环,输入是输入,却不知道for 循环里面也可以写输入。通过此题,学生可以更多了解 for 循环的用处:用来批量输入。

示例代码:

int sum = 0, a;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a;
sum += a;
}
cout << sum << endl;

相关练习:

5、输入 N 个数,求能整除 4 的个数

与上一题类似,我们在这里引入 if 条件,让学生了解,for 循环里面可以放前面学过的分支结构。

另外,本题的累加器变形为“计数”。让学生对计数的操作产生基本的认知。

示例代码:

int cnt = 0, a;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a;
if (a % 4 == 0) {
cnt++;
}
}
cout << cnt << endl;

6、输入 N 个数,统计值为 1、5 的个数

我们在上一题的基础上增加难度,让累加器可以是多个。

示例代码:

int cnt1 = 0, cnt5 = 0, a;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a;
if (a == 1) cnt1++;
if (a == 5) cnt5++;
}
cout << cnt1 << " " << cnt5 << endl;

相关练习:

7、输入 N 个数,求 N 个数的乘积

我们学会了在 for 循环中累加,计数,那更多的变化就是求乘积了。在求乘积的时候,这个累积的变量值要从 1 开始。

示例代码:

int mul = 1, a;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a;
mul = mul * a;
}
cout << mul << endl;

此题对应的线上练习是:《2019:【例4.4】求阶乘》

8、输入 N 和 M,求 M 的 N 次方

次方是乘积的另一种变化。线上的练习题是:《1069:乘方计算》

示例代码:

int mul = 1, m, n;
cin >> m >> n;
for (int i = 1; i <= n; ++i) {
mul = mul * m;
}
cout << mul << endl;

M 的 N 次方还有两种难度的加强,分别是:

  • 让学生考虑数据范围,用 long long 代替 int
  • 在数据范围超过 long long 时,取结果的末尾 5 位数

8、输入 N 个数,让你对这 N 个数做更复杂的操作

《1075:药房管理》一题就展示了一种更复杂的 for 循环。

原来我们不但可以累加,计数,求积,还可以做减法。

示例代码:

cin >> m >> n;
for (int i = 1;i <= n;i++){
cin >> a;
if (m >= a){
m = m-a;
} else {
b = b+1;
}
}
cout << b << endl;

9、求第 N 个斐波那契数

《1071:菲波那契数》 要求求第 K 个斐波那契数。

我们在这个 for 循环中实现了递推算法。递推是一个对新手来说很“神奇”的计算机算法,对于初学者来说,斐波那契数是最佳的一个学习例题,因为代码可以非常短。容易理解递推的核心思想。

示例代码:

#include <iostream>
using namespace std;
int main() {
int a=1, b=1, c=1;
int n;
cin >> n;
for(int i = 1; i <= n-2; i++){
c = b+a;
a = b;
b = c;
}
cout << c << endl;
return 0;
}

10、有一个数 N,满足 N*(N+1)*(N+2)*(N+3) = 1680 请问 N 的值是几

暴力枚举的基础代码也是 for 循环,我们用一个最简单的题目来引入枚举的思想。

示例代码:略。

11、for 的嵌套:金字塔

我们可以让学生试图输出一个二维的图形,比如输入 N,输出 N 层的金字塔。

金字塔的形状可以是这样:

*
**
***
****

也可以是这样:

   *
**
***
****

也可以是这样:

   *
***
*****
*******

借此让学生锻炼模拟的能力。

此题对应的线上练习是:《2027:【例4.13】三角形》

12、for 的嵌套:矩形

输入矩形的宽高,输出下面的形状。借此更一步强化学生模拟的能力。

*****
* *
* *
*****

此题对应的线上练习是:《1097:画矩形》

13、for 的逆序

for 循环中的三段,除了正向的写,也可以逆向的写。所以,我们可以让学生尝试把 1-N 倒着输出。

类似的,也可以提醒 for 的第三段i++其实也可以改成 i+=2之类的形式,实现各种跳着输出的情况。

教学实操

单人教学

在实操中,我们可以用一块白板进行代码的演示,然后不断擦写相关的关键代码,保留基础的 for 框架。这样方便学生观察到其中的变化与不变。

在没有白板的时候,也可以用电脑中的 IDE 或 PPT 来进行演示。

对于每一步的问题,可以让学生来应答。通过应答的过程,观察学生对此类问题的掌握情况,有选择的加速进度或者放慢进度,保证学生对知识的吸收到位。

多人教学

在多人教学的时候,可以让大家在纸上写下自己的答案,然后待大家都完成或大部分完成后,随机选择一位学生给其他人讲解,通过互助的方式,既锻炼了学生的表达,又强化了学生对知识的理解。

对于未完成的同学,可以让他反向提问,其他人帮忙解答。老师在这个过程中只需要监督整个过程,保证知识传递是正确的即可。

CATALOG
  1. 1. 背景和问题
  2. 2. 教学思考
  3. 3. 教学拆解
    1. 3.1. 1、用 for 循环输出数列
    2. 3.2. 2、用 for 循环输出 1-N 的和
    3. 3.3. 3、用 for 循环输出 1-N 的和的平均值
    4. 3.4. 4、输入 N,接着输入 N 个数求和
    5. 3.5. 5、输入 N 个数,求能整除 4 的个数
    6. 3.6. 6、输入 N 个数,统计值为 1、5 的个数
    7. 3.7. 7、输入 N 个数,求 N 个数的乘积
    8. 3.8. 8、输入 N 和 M,求 M 的 N 次方
    9. 3.9. 8、输入 N 个数,让你对这 N 个数做更复杂的操作
    10. 3.10. 9、求第 N 个斐波那契数
    11. 3.11. 10、有一个数 N,满足 N*(N+1)*(N+2)*(N+3) = 1680 请问 N 的值是几
    12. 3.12. 11、for 的嵌套:金字塔
    13. 3.13. 12、for 的嵌套:矩形
    14. 3.14. 13、for 的逆序
  4. 4. 教学实操
    1. 4.1. 单人教学
    2. 4.2. 多人教学