史小飞 宫彦军
基于任务驱动的《C++程序设计》教学改革探索
史小飞1宫彦军2
(1.湖南科技学院 图书馆,湖南 永州 425199;2.湖南科技学院 电子与信息工程学院,湖南 永州 425199)
在《C++程序设计》教学中采用任务驱动教学的优点是使学生能够了解编程的作用,通过解决具体的问题能提高学生的兴趣,同时从中能学习C++语言的语法。文中给出函数、函数模板和运算符重载三部分教学内容的任务设置,给出任务驱动教学的具体案例。
任务驱动教学法;C++语言;函数模板;运算符重载
有不少作者对C++程序设计这门课程的教学进行了研究,例如互动式教学法、兴趣驱动和案例教学等多种教学方法的配合、具体内容例如多重指针、while循环语句[1-4]。任务驱动法的特点是生动、形象和教学效果良好[5]。文[6]对于C++语言的项目教学法进行了研究,给出了任务设置的方案。文[7]给出虚函数实现多态的具体案例。有研究者对任务驱动和分组在C++语言教学中进行研究[8]。本文对课堂上的教学内容的任务布置上进行探索,给出了三部分教学内容任务的具体设置。
对于函数部分,首先把函数的基本概念讲清楚,函数包括函数名、返回值、形参,如何确定函数名、返回值及形参列表?其中难点是形参列表的设计。任务是“哥德巴赫猜想”的验证,任何大于等于4的偶数都可以分解为2个素数的和,这是一个具体的任务,有一定的挑战性,学生应该会感兴趣。通过这个任务,可以给大学生普及哥德巴赫猜想的知识,还可以起到教书育人的作用。
对于大于等于4的偶数n,找到满足下面的整数a,就可以验证哥德巴赫猜想,a和n-a都是素数,其中a大于0且小于n。设计一个判断大于0的整数是否为素数的函数。(1)给函数取个适当的名字prime,见名字应知道其大概的功能,是与素数有关;(2)确定形参列表,这个函数是判断一个整数是否为素数,即处理一个整数,形参为1个int型数;(3)返回值,判断一个数是否为素数,有2种情况,是素数或者不是素数,是素数用1表示,不是素数用0表示。这样其返回值为int型。具体的函数如下:
int prime(int n)
{
int a;
if(n==0||n==1) return 0;
for(a=2;a<=n-1;++a)
if(n%a==0) return 0;
return 1;
}
在具体讲解时要一步一步给学生演示,其中这里面也涉及算法的设计。上面素数的程序,对于素数循环次数会多,因为对于合数,存在一个小于等于其平方根的因子,改进如下:
int prime(int n)
{
int a;
if(n==0||n==1) return 0;
if(n==2) return 1;
for(a=2;a<=sqrt(n)+1;++a)
if(n%a==0) return 0;
return 1;
}
改进的程序对于合数的循环次数没有减少,但对于素数,例如对于素数1997,=44.6,循环次数为44次,按照原来的为1995次,相差很大。C++中存在bool型数据,因为判断素数只是存在2种情况,是素数和不是素数,这样判断素数的函数其返回值可以是bool型,把判断素数函数的返回值修改为bool型。
bool prime(int n)
{
int a;
if(n==0||n==1) return false;
if(n==2) return true;
for(a=2;a<=sqrt(n)+1;++a)
if(n%a==0) return false;
return true;
}
这样引入C++中一个新的数据类型bool类型。根据上面的验证哥德巴赫猜想的算法,具体的程序如下:
#include
using namespace std;
#include
bool prime(int n);
int main()
{
int n,a;
cout<<"请输入一个大于等于4的偶数!";
cin>>n;
for(a=2;a<=n-2;++a)
{
if(prime(a)&&prime(n-a))
{
cout< break; } } system("pause"); 法律应当把公共信息生产和服务作为监管者的主要职责。这主要包括提供民间融资市场总体供需信息、风险信息和信用信息,以减少融资主体信息盲区,降低信息获取成本。微观监管作为重要手段虽不可或缺,但须限制在较小范围内,包括适当的准入控制和合规性运行监管。 return 0; } 上面的程序省略了后面的判断素数的函数,把其补充上就是一个完整的验证哥德巴赫猜想的程序。通过这个例子可以知道设计一个函数的全过程,同时知道如何调用一个函数,判断素数的函数编好了,验证哥德巴赫猜想就比较容易,如果不利用函数而是在主函数里面进行素数的判断,那会很麻烦并且比较难编写,由此就体现了函数的重要性。 对于函数模板,可以通过排序程序模板的设计过程来学习函数模板是如何设计以及使用函数模板的好处。 首先是整数的排序程序的设计,(1)给函数取个适当的名字sort,见名字应知道其大概的功能;(2)确定形参列表,排序与数组有关,需要把数组传递到函数里面,同时要把数组元素的个数也要传递进去,接收数组的变量是指针,接收整数的是整型数,这样形参就是int *和int;(3)返回值,因为这是数组的排序,是执行一个具体的过程,返回值为void。这里采用冒泡法排序,具体的程序如下: void sort(int *c, int n = 5) { bool flag = false; { flag = true; for (int j = 0; j < n-1-i; ++j) { if (c[j]>c[j+1]) { flag = false; swap(c[j], c[j+1]); } } if (flag)break; } } 修改为函数模板,只是引入一个虚拟的类型,函数模板如下: template void sort(T *c, int n = 5) { bool flag = false; for (int i = 0; i < n-1;++i) { flag = true; for (int j = 0; j < n-1-i; ++j) { if (c[j]>c[j+1]) { flag = false; swap(c[j], c[j+1]); } } if (flag)break; } } 具体的测试程序如下: #include #include using namespace std; #include "my.h" int main() { const int n=5; int c[n]; int i; cout<<"请输入"< for (i = 0; i < n; ++i) cin>>c[i]; sort(c,n); cout<<"从小到大的排序如下:"< for (i = 0; i < n; ++i) cout< system("pause"); return 0; } 其中函数模板放到my.h这个头文件里面。 把测试程序的int c[n];修改为double c[n];同时提示输入的部分修改为cout<<"请输入"< 运算符重载,首先一个例子是复数的例子,这里面不列出,引入另外1个任务是按学生的成绩从高到低排序,先讲不用运算符重载的程序。学生按照成绩从高到低的排序。为了利用前面的从小到大的排序函数模板,因为小的排到后面,本文重载学生类的大于运算符,2个学生之间比较大小,成绩小的大,这样利用前面的排序函数模板,成绩小的排在后面。 #include #include using namespace std; class Student { public: void input() { cout<<"输入学号姓名一门成绩:"; cin>>num>>name>>score; } void output() { cout< } bool operator>(const Student &stu) { if(score else return false; } private: int num; string name; float score; }; template void sort(T *c, int n = 5) { bool flag = false; for (int i = 0; i < n-1 ; ++i) { flag = true; for (int j = 0; j < n-1-i; ++j) { if (c[j]>c[j+1]) { flag = false; swap(c[j], c[j+1]); } } if (flag)break; } } int main() { int n,i; Student *P; cout<<"请输入学生的个数:"; cin>>n; P=new Student[n]; for(i=0;i P[i].input(); sort(P,n); for(i=0;i P[i].output(); delete []P; return 0; } 因为函数模板只是用到大于运算符“>”,所以对于学生类只需要重载大于运算符“>”即可,这样学生加深理解了运算符的重载,只需要重载一个比较运算符就可以利用通用的函数排序模板实现了排序。在讲这个任务之前可以讲不用排序函数模板的排序。 void sort(Student *c, int n = 5) { bool flag = false; for (int i = 0; i < n-1 ;++i) { flag = true; for (int j = 0; j < n-1-i; ++j) { if (c[j].getscore() { flag = false; swap(c[j], c[j+1]); } } if (flag)break; } } 因为数据成员为私有成员,学生比较要用到成绩,所以需要增加一个public的成员函数getscore(),用来获得学生的成绩。如果要直接在这个函数里面访问私有的数据成员,可以把上面的函数声明为Student类的友元函数。 [1] 郭丰娟,王晓辉.《C++程序设计》互动教学改革实践[J].中国科技信息,2012,(11):232. [2] 郭艳燕,任满杰,利坚,等.C++程序设计课程中多种教学方法的配合使用[J].计算机教育,2012,(15):78-81. [3] 黄文晓.C++/C语言的多重指针课堂教学设计[J].中国外资, 2012,(16):278-280. [4] 姜妍.C++中while循环语句教学设计探讨[J].科技创新导报, 2012,(5):205. [5] 付丽群,张晟涛,张准,等.任务驱动法在C++程序设计教学中的应用[J].数字技术与应用,2013,(2):206. [6] 方开红.项目教学法在C++语言课程教学的应用与探讨[J]. 福建电脑,2012,(8):140-142. [7] 柯栋梁,李军利.C++虚函数实现多态之案例驱动教学方法探讨[J].安徽工业大学学报(社会科学版),2012,(4):114-115. [8] 魏小琴,祝元仲,冯元元.任务驱动与分组教学法在《C++程序设计》实验教学中的应用研究[J].科技信息,2012,(7): 36-37. (责任编校:何俊华) 2015-05-08 湖南省教育厅资助科研项目(12A054);湖南省科技计划资助(批准号: 2012FJ3052);湖南科技学院电路与系统重点学科建设项目资助。 史小飞(1970-),女,吉林梨树人,助理馆员,主要研究方向为图书馆学、情报学、计算机程序设计。 G642.0 A 1673-2219(2015)10-0094-032 函数模板部分
3 运算符重载