史小飛 宮彥軍
?
基于任務驅動的《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 運算符重載