李伟+郑珊珊+牧剑波
摘 要:“C语言程序设计”课程是信息类专业的一门非常重要的基础课程,其中函数是该课程的重点和难点之一,该文作者结合实际教学情况,对函数的内容安排、函数的设计和函数的参数传递等方面进行了探讨,实践证明,该方法取得了良好的效果,学生通过函数进一步理解了模块化程序设计的思想。
关键词:C语言 函数 参数传递
中图分类号:TP312 文献标识码:A 文章编号:1674-098X(2014)11(a)-0135-02
“C语言程序设计”课程是信息类专业的一门非常重要的基础课程,这门课程的主要目的就是让学生以C语言为例了解高级程序设计语言的结构,掌握程序设计的基本思想,具备初步的分析问题和用计算机解决问题的能力。函数是C语言程序设计课程的重点和难点,它体现了模块化程序设计的思想,将一个复杂的问题分解成一个个小而简单的问题,通过解决一个个小问题进而实现大的复杂问题的求解。在函数的教学中,经常会有教师不好教学生学不懂的现象,学生学完函数后,基本概念和结构语法都清楚,但是针对具体的问题就无从下手,教学效果一直不是太好。笔者在多年C语言教学的实践基础上,结合我校学生的具体情况,对函数部分的内容组织和教学方法做了一些探讨。
1 教学内容和安排
函数部分一般按以下内容进行教学。
(1)函数的作用和分类:标准库函数和自定义函数。
(2)函数定义的基本格式:无参函数、有参函数和空函数。
(3)函数的参数传递:值传递和地址传递。
(4)函数的返回值:无返回值、一个返回值和多个返回值。
(5)函数的调用:作为单独语句、作为表达式和作为函数参数。
(6)函数的递归调用和嵌套调用。
(7)函数的声明:声明的位置、格式和省略情况。
(8)变量的作用域:全局变量和局部变量。
(9)变量的存储类型及生存期:自动变量、静态变量、外部变量和寄存器变量。
可以看出,函数部分的内容非常多,而且会有许多新的概念突然介入,有相当一部分教材,以谭浩强教授的《C程序设计》(第四版)为代表,将函数作为单独一章放在选择控制结构和数组之后,把函数相关的上述所有内容都放在这一章中介绍,然后在后续的指针、结构体和文件等章节中又几乎没有函数的踪影,程序的主体仍然放到main()函数中去讲解,笔者认为这样的内容编排结构不利于学生对函数的把握,它会导致函数和其他内容脱节,给学生造成这是专门的一章,不学或学不好对其它内容不会产生多大影响的印象,结果到课程结束时仍然对函数知之甚少,平时也几乎没用函数来编写过程序,导致到了学期末学生在编程时仍然习惯把所有程序都放到一个main()函数中去编写,很少有模块化程序设计的思想,为以后编写复杂程序或者参加团队合作埋下了隐患。
该文作者在讲授函数这一部分时,参考了哈尔滨工业大学苏小红教授的高教版《C语言程序设计》(第二版)的内容编排,把函数提到了数组之前介绍,而且从函数这一章开始,后面几乎所有的程序都是按模块化思想将程序分成一个个小函数,再通过main()函数调用这些函数来实现主体功能,并且在后续内容的讲解中,不断强化学生对函数的把握,强化学生模块化程序设计的思想,学生在学习的过程当中,不断地复习巩固着函数的知识,不断地感受着模块化程序设计的思想,也逐渐养成了用函数设计程序的习惯,实践表明,到学期末的时候,大多数学生都可以写一些简单的函数并通过main()函数调用来进行程序设计。
2 函数的设计思想和设计方法
在进行程序设计时,很多学生感到困惑、难以理解和掌握的是什么时候需要设计函数和该设计什么样的函数,形参和返回值该如何设置。对这个问题,笔者认为在讲解的时候要着重把握几点。
首先,在确定什么时候该设计函数时,需要先对整个程序的过程有个把握,确定程序的主体功能,这样,对需不需要设计函数及对哪些部分可以设计函数就有了较为明确的答案。例如:从键盘上输入一个整数n(n>1且n<10),输出1!+2!+3!+...+n!的值。
对程序进行分析后,可以得出程序主体可以分成两个步骤:
输入一个整数n;
输出1!+2!+3!+...+n!的值。
在第2) 步骤中,由于重复用到了求阶乘的功能,所以如果把求阶乘这部分设计成一个函数,将会对第2) 步的编程起到简化的作用。这样,经过初步分析,可以确定需要设计一个函数,此函数的功能是对给定的一个整数m,求出其阶乘。
函数的功能确定后,接着就可以着手设计函数了。具体到函数设计时,很多学生的疑惑是怎么设计函数的参数和返回值,在这里,笔者建议学生采用“黑匣子”的方法设计函数,即不需要管函数的内部结构,把它看做一个“黑匣子”,只从外部的功能要求来确定函数应该具备什么样的功能,进而确定主函数在调用该函数时需要传递给它什么参数,它在返回主调函数时又需不需要返回值或需要返回几个值。在上个例子中,函数的功能确定是求阶乘,在主函数调用它时需要告诉它对谁求阶乘,即传递给该函数阶乘的阶数m,函数调用结束后,需要m的阶乘返回主调函数,即只需要返回一个值,如图1所示。
由此,我们得出此函数的相关内容:
函数功能:求出整数m的阶乘m!
函数入口参数:一个形参,整形变量m表示阶乘的阶数
函数返回值:一个返回值,返回m!的值
这段信息可以作为注释放在函数的开头以便让其他程序员有足够的信息了解如何使用该函数。然后根据C语言中函数的定义格式可以写出求阶乘函数定义:int fact(int m);考虑到m!的范围,我们可以将其修改定义为:long fact(int m);endprint
至此,函数的第一个难点就解决了。
3 函数的参数传递
在函数需要有多个返回值时,仅仅一个return就很难满足要求了,这里就需要利用指针或全局变量将函数中的多个值传递到主调函数中,这属于函数的参数传递问题。函数的参数传递是函数部分的又一个难点,可以分为值传递和地址传递,因为还关系到指针的应用,学生一时间很难理解和掌握。鉴于这一点,笔者采用形象类比法结合内存空间讲解了值传递和地址传递的区别。
函数在被调用时新开辟了一段内存空间,所有形参和函数内部变量都在这个内存空间中被访问或修改,一旦返回主调函数这段内存空间也就被释放掉,形参的值不会传递给实参,影响到主调函数。即在进行值传递时相当于有一个复制操作,即将实参的值赋给函数空间的形参,这是一个单向传递,因此,对形参的改变不会影响到实参。而地址传递的实质是将主调函数中的某个或多个地址放到被调函数中进行访问,此操作间接访问到了主调函数中的变量,因而影响到了主调函数中的变量值。
上述讲法需要学生建立内存空间的概念,要对程序的存储空间有所认识,相当一部分同学表示难以理解。笔者结合大一学生都学过计算机引论的实际情况,将值传递比喻为将计算机中的某一文件file1.doc拷贝给别人,别人拷走后可以随便修改这个文件的内容,这些修改都不会影响到原来的文件file1.doc。当传递的是地址的时候,即使用指针变量作函数参数时,相当于把机器密码、要修改的文件路径及文件名(如d:\project\file1.doc)告诉了别人,别人在修改时直接针对file1.doc,进行修改后,file1.doc的内容肯定也会发生改变,这就是地址传递。经过这样形象的比喻后,学生多表示容易理解,在写程序时会有意识地考虑需要进行的是值传递还是地址传递,形参该设置成普通变量还是指针变量,教学效果有所改善。
4 结语
实践证明,在笔者进行的函数教学中,相当一部分同学对函数有了形象的认识,更深地理解了模块化程序设计的思想,取得了良好的学习效果。学无止境,教亦无止境。除了以上几点,只函数部分就还有很多可以继续深入挖掘的东西,比如从函数有无参数方面,函数有无返回值或是否有多个返回值方面,变量的存储类型和生存期方面等等,这些都值得我们教师不断地研究不断地探讨。但归根结底,如何让学生容易掌握要点,如何让学生发自内心地喜欢学习、爱上学习并善于主动学习,笔者认为才是教师的最终目的。
参考文献
[1] 苏小红.C语言程序设计[M].2版.高等教育出版社,2013.
[2] 谭浩强.C程序设计[M].4版.清华大学出版社,2011.
[3] 何钦铭.“程序设计基础”课程教学实施方案[J].中国大学教学,2010(5).
[4] 董鑫正.C语言教学中函数参数传递问题探讨[J].电脑知识与技术,2012(3).endprint
至此,函数的第一个难点就解决了。
3 函数的参数传递
在函数需要有多个返回值时,仅仅一个return就很难满足要求了,这里就需要利用指针或全局变量将函数中的多个值传递到主调函数中,这属于函数的参数传递问题。函数的参数传递是函数部分的又一个难点,可以分为值传递和地址传递,因为还关系到指针的应用,学生一时间很难理解和掌握。鉴于这一点,笔者采用形象类比法结合内存空间讲解了值传递和地址传递的区别。
函数在被调用时新开辟了一段内存空间,所有形参和函数内部变量都在这个内存空间中被访问或修改,一旦返回主调函数这段内存空间也就被释放掉,形参的值不会传递给实参,影响到主调函数。即在进行值传递时相当于有一个复制操作,即将实参的值赋给函数空间的形参,这是一个单向传递,因此,对形参的改变不会影响到实参。而地址传递的实质是将主调函数中的某个或多个地址放到被调函数中进行访问,此操作间接访问到了主调函数中的变量,因而影响到了主调函数中的变量值。
上述讲法需要学生建立内存空间的概念,要对程序的存储空间有所认识,相当一部分同学表示难以理解。笔者结合大一学生都学过计算机引论的实际情况,将值传递比喻为将计算机中的某一文件file1.doc拷贝给别人,别人拷走后可以随便修改这个文件的内容,这些修改都不会影响到原来的文件file1.doc。当传递的是地址的时候,即使用指针变量作函数参数时,相当于把机器密码、要修改的文件路径及文件名(如d:\project\file1.doc)告诉了别人,别人在修改时直接针对file1.doc,进行修改后,file1.doc的内容肯定也会发生改变,这就是地址传递。经过这样形象的比喻后,学生多表示容易理解,在写程序时会有意识地考虑需要进行的是值传递还是地址传递,形参该设置成普通变量还是指针变量,教学效果有所改善。
4 结语
实践证明,在笔者进行的函数教学中,相当一部分同学对函数有了形象的认识,更深地理解了模块化程序设计的思想,取得了良好的学习效果。学无止境,教亦无止境。除了以上几点,只函数部分就还有很多可以继续深入挖掘的东西,比如从函数有无参数方面,函数有无返回值或是否有多个返回值方面,变量的存储类型和生存期方面等等,这些都值得我们教师不断地研究不断地探讨。但归根结底,如何让学生容易掌握要点,如何让学生发自内心地喜欢学习、爱上学习并善于主动学习,笔者认为才是教师的最终目的。
参考文献
[1] 苏小红.C语言程序设计[M].2版.高等教育出版社,2013.
[2] 谭浩强.C程序设计[M].4版.清华大学出版社,2011.
[3] 何钦铭.“程序设计基础”课程教学实施方案[J].中国大学教学,2010(5).
[4] 董鑫正.C语言教学中函数参数传递问题探讨[J].电脑知识与技术,2012(3).endprint
至此,函数的第一个难点就解决了。
3 函数的参数传递
在函数需要有多个返回值时,仅仅一个return就很难满足要求了,这里就需要利用指针或全局变量将函数中的多个值传递到主调函数中,这属于函数的参数传递问题。函数的参数传递是函数部分的又一个难点,可以分为值传递和地址传递,因为还关系到指针的应用,学生一时间很难理解和掌握。鉴于这一点,笔者采用形象类比法结合内存空间讲解了值传递和地址传递的区别。
函数在被调用时新开辟了一段内存空间,所有形参和函数内部变量都在这个内存空间中被访问或修改,一旦返回主调函数这段内存空间也就被释放掉,形参的值不会传递给实参,影响到主调函数。即在进行值传递时相当于有一个复制操作,即将实参的值赋给函数空间的形参,这是一个单向传递,因此,对形参的改变不会影响到实参。而地址传递的实质是将主调函数中的某个或多个地址放到被调函数中进行访问,此操作间接访问到了主调函数中的变量,因而影响到了主调函数中的变量值。
上述讲法需要学生建立内存空间的概念,要对程序的存储空间有所认识,相当一部分同学表示难以理解。笔者结合大一学生都学过计算机引论的实际情况,将值传递比喻为将计算机中的某一文件file1.doc拷贝给别人,别人拷走后可以随便修改这个文件的内容,这些修改都不会影响到原来的文件file1.doc。当传递的是地址的时候,即使用指针变量作函数参数时,相当于把机器密码、要修改的文件路径及文件名(如d:\project\file1.doc)告诉了别人,别人在修改时直接针对file1.doc,进行修改后,file1.doc的内容肯定也会发生改变,这就是地址传递。经过这样形象的比喻后,学生多表示容易理解,在写程序时会有意识地考虑需要进行的是值传递还是地址传递,形参该设置成普通变量还是指针变量,教学效果有所改善。
4 结语
实践证明,在笔者进行的函数教学中,相当一部分同学对函数有了形象的认识,更深地理解了模块化程序设计的思想,取得了良好的学习效果。学无止境,教亦无止境。除了以上几点,只函数部分就还有很多可以继续深入挖掘的东西,比如从函数有无参数方面,函数有无返回值或是否有多个返回值方面,变量的存储类型和生存期方面等等,这些都值得我们教师不断地研究不断地探讨。但归根结底,如何让学生容易掌握要点,如何让学生发自内心地喜欢学习、爱上学习并善于主动学习,笔者认为才是教师的最终目的。
参考文献
[1] 苏小红.C语言程序设计[M].2版.高等教育出版社,2013.
[2] 谭浩强.C程序设计[M].4版.清华大学出版社,2011.
[3] 何钦铭.“程序设计基础”课程教学实施方案[J].中国大学教学,2010(5).
[4] 董鑫正.C语言教学中函数参数传递问题探讨[J].电脑知识与技术,2012(3).endprint