背景和问题
小学生在学习编程的时候,像变量,赋值,输入,输出,分支这些逻辑相对容易理解。因为这与人类真实世界的很多行为相似,所以学生会很容易吸收。具体来说:
- 变量其实就是我们平时取的“名字”或者“外号”,用于指代一种特定物品。
- 赋值相当于为这种特定物品指定一种属性值,像是苹果的重量,价格一样。
- 输入和输出在很多电子产品中都有接触,孩子现在很小就接触手机,非常容易理解键盘就是一种输入,屏幕显示就是一种输出。
- 分支就是我们自然语言中的“如果…就”,非常容易类比。
但是,for 循环由于其很难与现实世界“类比”,所以成为小学生学习编程的第一个障碍。
如何理解 for 循环,并且灵活运用 for 循环,成为一个教学难点。
教学思考
我在教学 for 循环的时候发现,如果我们用尽量渐进式的方式,让孩子刚开始接触到的 for 循环与现实世界数学中的数列一一对应。然后,再一步一步拔高难度,随着难度提高,最终 for 循环可以实现求解“非波拉切数列”以及“小数点后 10000 位”这类已经高度变型的题目。
因为每一步的难度提升梯度很小,所以学生虽然找不到现实世界类比,但终于还是比较容易理解整个渐进变化的过程。
这就类似于我们学立体几何前先学平面几何,学平面几何前先学点线面一样。从微小的简单事物开始,我们最终可以创造整个世界。
以下是我对 for 循环的具体教学拆解。
教学拆解
1、用 for 循环输出数列
输出从 1-N 的等差数列是使用 for 循环最基础形式。我们先用这个引入,让孩子先初步了解 for 循环的三段形式。
for 循环的三段式其实对初学者来说还是有点绕,借此环节把 for 的基本格式熟悉。
示例代码:
cin >> n; |
2、用 for 循环输出 1-N 的和
累加器的写法对于初学者来说是一个小障碍,但是累加器与 for 循环的结合使用在之后的变化很常见,所以我们在这个阶段把累加器引入,帮助孩子建立累加器的使用习惯。
示例代码:
int sum = 0; |
注:对于不习惯 += 的学生,也可以刚开始用 sum = sum + i
来教学,减少学生的陌生感。
此题对应的线上练习是:《2016:【例4.1】for循环求和》
此题也可以进一步变化为:分别求奇数和、偶数和。让学生学会在 for 里面嵌入 if 表达式。
- 奇偶数之和线上练习:《2018:【例4.3】输出奇偶数之和》
- 奇数求和的线上练习:《1065:奇数求和》
3、用 for 循环输出 1-N 的和的平均值
平均值的计算涉及整除的概念,需要在除之前将被除数转化为小数,同时需要用 iomanip 头文件中的函数来控制输出格式,这一编程技巧正好在这一步引入,让学生逐步熟悉对输出的控制。
示例代码:
|
此题对应的线上练习是:《1060:均值》
4、输入 N,接着输入 N 个数求和
大部分学生以为 for 循环是 for 循环,输入是输入,却不知道for 循环里面也可以写输入。通过此题,学生可以更多了解 for 循环的用处:用来批量输入。
示例代码:
int sum = 0, a; |
相关练习:
5、输入 N 个数,求能整除 4 的个数
与上一题类似,我们在这里引入 if 条件,让学生了解,for 循环里面可以放前面学过的分支结构。
另外,本题的累加器变形为“计数”。让学生对计数的操作产生基本的认知。
示例代码:
int cnt = 0, a; |
6、输入 N 个数,统计值为 1、5 的个数
我们在上一题的基础上增加难度,让累加器可以是多个。
示例代码:
int cnt1 = 0, cnt5 = 0, a; |
相关练习:
7、输入 N 个数,求 N 个数的乘积
我们学会了在 for 循环中累加,计数,那更多的变化就是求乘积了。在求乘积的时候,这个累积的变量值要从 1 开始。
示例代码:
int mul = 1, a; |
此题对应的线上练习是:《2019:【例4.4】求阶乘》
8、输入 N 和 M,求 M 的 N 次方
次方是乘积的另一种变化。线上的练习题是:《1069:乘方计算》
示例代码:
int mul = 1, m, n; |
M 的 N 次方还有两种难度的加强,分别是:
- 让学生考虑数据范围,用 long long 代替 int
- 在数据范围超过 long long 时,取结果的末尾 5 位数
8、输入 N 个数,让你对这 N 个数做更复杂的操作
《1075:药房管理》一题就展示了一种更复杂的 for 循环。
原来我们不但可以累加,计数,求积,还可以做减法。
示例代码:
cin >> m >> n; |
9、求第 N 个斐波那契数
《1071:菲波那契数》 要求求第 K 个斐波那契数。
我们在这个 for 循环中实现了递推算法。递推是一个对新手来说很“神奇”的计算机算法,对于初学者来说,斐波那契数是最佳的一个学习例题,因为代码可以非常短。容易理解递推的核心思想。
示例代码:
|
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 来进行演示。
对于每一步的问题,可以让学生来应答。通过应答的过程,观察学生对此类问题的掌握情况,有选择的加速进度或者放慢进度,保证学生对知识的吸收到位。
多人教学
在多人教学的时候,可以让大家在纸上写下自己的答案,然后待大家都完成或大部分完成后,随机选择一位学生给其他人讲解,通过互助的方式,既锻炼了学生的表达,又强化了学生对知识的理解。
对于未完成的同学,可以让他反向提问,其他人帮忙解答。老师在这个过程中只需要监督整个过程,保证知识传递是正确的即可。