王荣良
编程学习是进入计算机专业领域的入门课程。大学一年级计算机专业的学生都会学习一门程序设计语言的课程,他们在学会一种计算机高级语言的同时,也大致理解了计算解决问题的一般过程。我国基础教育也开设了类似的程序设计课程,该课程从早期的BASIC语言、LOGO语言,到后来的Pascal语言、VB、VC,直到现在流行的Scratch、Pathon,已经有30多年的历史了。在这30多年中,有关中小学生开展计算机编程学习教育价值的争论一直就没有停息过。当前,计算思维教育的兴起给中小学生学习编程提供了新的价值取向。显然,计算思维作为计算机科学的学科思维,主要是在计算机专业的知识与技能学习过程中渗透的。因此,编程学习也应该是计算思维教育的有效途径。但这并不等于说,学习编程就一定能培养计算思维。
在程序设计“循环结构”教学中,有一个经典题例,就是“1+2+3+……+100”的求和。如果在高中阶段学习该知识点,学生们都已经知道了高斯公式,并且还会质疑这一算法为何不用高斯公式而要用笨拙的循环,那么,是不是可以说,用循环就是体现计算机解决问题的思路,用循环就是体现计算思维呢?教师不妨站在计算机科学基础概念的角度,对计算机进行“1+2+3+……+100”的求和操作进行细致的分析。
第一,这是编程学习中的一个典型例子,但这个典型例子引用的初衷并不是从计算思维教育的角度出发的。其典型之处在于为讲解循环结构提供方便,非常直观地提供了循环结构的基本要素,即循环体和循环条件。例子本身很容易理解,是否正确实现也很容易判断。因此,该例子的教学功能是学习一个典型累加求和的算法,同时也帮助学生理解循环结构。仅就这点而言,这个例子对计算机执行循环的过程的技术细节理解有帮助,但不能算是计算思维的典型例子。
第二,关于循环结构实施“1+2+3+……+100”求和的价值判断问题。评价一种计算的优劣,时间开销和空间开销是两个重要指标。对于已知计算量的运算,如本例中的99次求和运算,是可以用顺序结构来完成的。而站在计算开销的角度来考虑,用顺序结构来解决,时间开销是小的,但程序代码所占的存储容量较大。那么,为什么要用循环结构来实现呢?一方面,是因为很多应用是不能用顺序结构来简单代替的;另一方面,是因为不便于人的思维和表达。要让计算机为人类做事,就需要让计算机知道做什么,这就需要简约、明确地告诉计算机,这种表达方式是为人服务的,也是人的思维。这种形式化表达是计算思维的一部分,这也从一个侧面说明计算思维是人的思维,而不是计算机的。
第三,在实际应用中,如果已知高斯公式,那么应该用高斯公式来计算,还是用这种求和的方法来计算呢?答案是肯定的,那就是用高斯公式来计算。因为用高斯公式来计算,就不需要用累加的方法来实现,降低了计算的复杂度,这也是计算学科追求的目标。这一点在教学过程中应该向学生交代清楚,不能让他们产生这样的错误理解:不用高斯公式,而采用求和的笨办法,是为了满足计算机的需求,计算机总是用最原始的方法来解决问题的。事实上,如果一个计算问题有现成的解析公式,那么计算机肯定用现成公式。用高斯公式来表达“1+2+3+……+100”的求和,是一种建模的过程。这是在计算公式层面上的建模,而建模也是计算思维的一部分。
第四,同样的问题,如果学生并不知道高斯公式,那么教师教学过程的开展可能有两条途径:①采用累加求和的方式用循环结构实现;②先推导出高斯公式,然后用高斯解析式,直接用赋值语句编程。用累加方法还是用公式计算,取决于人的需要,或者说哪种方式更能为人解决问题提供便捷。这两种教学的方式,体现了计算思维不同的侧重点:①在于循环结构的形式化表达;②对有待解决问题的抽象和数学建模的过程。当然,有一点还是需要注意的,就是在教学过程中推导高斯公式所花费的开销。如果需要花费相对比较多的时间和精力去推导高斯公式,那么整个解决求和问题的教学过程就成了数学课,而不是程序设计课。
第五,有一些例子很难用数学解析式来表达答案,但可以用循环结构来实现。例如,上海高中信息科技教材中有关“循环结构”的典型例子:一张单据上一个5位数字组成的编号,其千位数和百位数处已变得模糊不清,只知道这个5位数是57或67的倍数,求这个满足条件的5位数。这个问题可以通过两重循环枚举算法来解决。但对于另外一个形式的问题——求解一元二次方程,如果已知存在整数解和解的范围,那么可以用循环的方法来解决;如果学生已经学习了一元二次方程的求解公式,那么应该直接用公式,使用解析法来求解,因为这种方法更直接,效率更高。更進一步,针对“鸡兔同笼”的问题,对小学生而言,可以用枚举的方法来解决,这是一个典型的发挥计算机特长弥补人的智力的解决问题的方法,在培养学生应用计算机解决问题的能力的同时,也反映出利用计算机解决问题这一思想,即让计算机用构造的方法通过简单重复计算来解决人类复杂的智力问题;反之,如果让学生先学习推导反映“鸡兔同笼”问题的方程式,然后用解析法由计算机来实现,那么,这主要就是考验学生的奥数技能了。
综上所述,用循环的方法实现“1+2+3+……+100”的累加求和,是一个用于编程学习的典型例子,但不能算是计算机实际应用的典型例子,因为在实际程序实现中,一般只会在已有循环结构实现其他功能的情况下用这种方法,很少会专门编写循环语句只为单一累加求和。其实,更为典型的应用是计数器,即i=i+1的实现,在循环体中计算循环次数,这是一个将人解决问题的方法用计算机来实现的实例。
从计算思维教育的角度出发,其关键在于能对需要解决的问题进行抽象,形成计算机能够理解的形式化表达,并且让计算机自动地去计算。至于是用循环结构累加实现,还是用高斯公式来编程序,则取决于完成这一计算的工作基础以及价值判断,这两种实现方法都能体现计算思维。
在计算思维成为热点的当下,在大规模开展计算思维教育的时刻,教师需要对计算思维的本质和细节仔细研究,而不是简单地把编程教育理解成计算思维教育。周以真教授提出的“计算思维是运用计算机科学的基础概念进行问题求解、系统设计,以及人类行为理解等涵盖计算机科学之广度的一系列思维活动”不是一句空洞的话,而是基于对计算机科学基础知识和基本理论的理解。对中小学生而言,学习Word、Excel等应用软件的使用,只是体验了计算机技术给人们生活、学习带来的便捷,而学习计算机编程,则是为理解计算机学科这个神秘世界打开了一扇小门。教师若要把计算思维有效地传达给学生,让学生在学习计算机学科知识的前提下接受计算思维教育,就要对计算机学科知识有一个清晰的认识,对计算过程有一个明确的判断,对计算思维有全面而深刻的理解。