摘 ?要:“C語(yǔ)言程序設(shè)計(jì)”課程是計(jì)算機(jī)類(lèi)專(zhuān)業(yè)的一門(mén)基礎(chǔ)課程,旨在引導(dǎo)學(xué)生建立邏輯思維,體會(huì)編程的樂(lè)趣;然而市面上絕大多數(shù)教材中的案例,多以解析數(shù)學(xué)題、科學(xué)常數(shù)等為主,學(xué)習(xí)起來(lái)呆板乏味,因此引入時(shí)下非常流行的“搶紅包”游戲,比起做數(shù)學(xué)題更接“地氣”,“搶紅包”程序用到了if-else、循環(huán)、函數(shù)、數(shù)組等知識(shí),幾乎涵蓋課程大綱中需要學(xué)生掌握的所有知識(shí)點(diǎn),是一個(gè)很好的綜合項(xiàng)目,讓學(xué)生自己玩自己編寫(xiě)的游戲,學(xué)生更加有學(xué)習(xí)的動(dòng)力和成就感,對(duì)學(xué)習(xí)這門(mén)課程有很大的促進(jìn)作用。
關(guān)鍵詞:C語(yǔ)言;項(xiàng)目驅(qū)動(dòng);教學(xué)案例;搶紅包
中圖分類(lèi)號(hào):TP312 ? ? 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):2096-4706(2020)04-0095-03
Abstract:“C Language Programming” is a basic course for computer major. It aims to guide students to establish logical thinking and experience the fun of programming;however,most of the cases in the textbooks on the market are mainly based on the analysis of mathematical problems and scientific constants,which are dull to learn. Therefore,the popular game of “snatching red envelopes” is introduced,which is more “earthly” than doing mathematical problems,“snatching red envelopes” program uses if-else,cycle,function,array and other knowledge,almost covering all the knowledge points that students need to master in the curriculum outline. It is a good comprehensive project,so that students can play their own games,and students have more motivation and sense of success,which has a great role in promoting the learning of such courses.
Keywords:C language;project driven;teaching cases;snatching red envelopes
0 ?引 ?言
“C語(yǔ)言程序設(shè)計(jì)”課程是計(jì)算機(jī)類(lèi)相關(guān)專(zhuān)業(yè)的專(zhuān)業(yè)基礎(chǔ)課程,本科院校和高職院校相關(guān)專(zhuān)業(yè)都在開(kāi)設(shè)本門(mén)課程。學(xué)生通過(guò)學(xué)習(xí),熟悉C語(yǔ)言的開(kāi)發(fā)環(huán)境,掌握C語(yǔ)言的基本語(yǔ)句,初步了解和掌握程序設(shè)計(jì)的基本方法,為學(xué)習(xí)后繼其他專(zhuān)業(yè)課程做好鋪墊?!癈語(yǔ)言程序設(shè)計(jì)”課程對(duì)培養(yǎng)學(xué)生的邏輯思維素質(zhì)、編程能力、科學(xué)精神都具有十分重要的作用。本學(xué)習(xí)領(lǐng)域強(qiáng)調(diào)以學(xué)生為主體、知識(shí)為技能服務(wù),培養(yǎng)學(xué)生的自主學(xué)習(xí)能力、創(chuàng)新能力和團(tuán)隊(duì)合作能力,爭(zhēng)取通過(guò)一個(gè)學(xué)期的課程學(xué)習(xí),在短時(shí)間內(nèi)讓學(xué)生掌握編程思想。
在實(shí)際講授“C語(yǔ)言程序設(shè)計(jì)”的過(guò)程中,大多數(shù)教材用求奇數(shù)、偶數(shù)、約數(shù)、公約數(shù)、最小公約數(shù)、最大公約數(shù),求精確到指定位數(shù)的π值、求平方、平方根、求冪、求裴波那契數(shù)列等案例;這些案例非常經(jīng)典,完全能讓學(xué)生掌握對(duì)應(yīng)的知識(shí)點(diǎn),但學(xué)生普遍反映這些數(shù)學(xué)題案例枯燥、生澀、難懂。
1 ?案例背景
在軟件設(shè)計(jì)教學(xué)過(guò)程中,如果缺少和生活緊密相關(guān)的主題,就難以激勵(lì)學(xué)生產(chǎn)生主動(dòng)學(xué)習(xí)編程的動(dòng)力。老師在設(shè)計(jì)“C語(yǔ)言程序設(shè)計(jì)”教學(xué)案例時(shí),需要按照日常生活中實(shí)際的、具體的情景進(jìn)行設(shè)計(jì),使用項(xiàng)目教學(xué)法調(diào)動(dòng)學(xué)生學(xué)習(xí)的主觀能動(dòng)性,讓學(xué)生在項(xiàng)目實(shí)踐過(guò)程中充分體會(huì)到成就感,從而能運(yùn)用編程思維去思考和解決日常生活中的實(shí)際問(wèn)題,進(jìn)一步提升學(xué)生的思考能力和表達(dá)能力。
生活化情境教學(xué)能營(yíng)造出輕松愉悅的課堂氛圍,使課堂學(xué)習(xí)不再枯燥乏味,學(xué)生不再埋頭玩手機(jī)和呼呼酣睡,教師能通過(guò)學(xué)生表情了解學(xué)生疑惑所在、對(duì)重難點(diǎn)內(nèi)容著重闡述;學(xué)生不理解的知識(shí)隨時(shí)跟老師交流,在情境中師生相互進(jìn)行引導(dǎo)與啟發(fā),增強(qiáng)師生互動(dòng),讓學(xué)生學(xué)會(huì)主動(dòng)學(xué)習(xí),探求新知識(shí),構(gòu)建知識(shí)鏈。
這些年來(lái)QQ群和微信群的搶紅包游戲如火如荼,是一個(gè)非常好的生活化案例。設(shè)定紅包總金額money和分發(fā)人數(shù)n,程序就生成總金額為money的n個(gè)隨機(jī)紅包,本案例就探討實(shí)現(xiàn)隨機(jī)紅包的算法。
2 ?項(xiàng)目設(shè)計(jì)
2.1 ?開(kāi)發(fā)環(huán)境
開(kāi)發(fā)語(yǔ)言:C語(yǔ)言。
開(kāi)發(fā)工具:Visual Studio 2012/Visual C++6.0。
2.2 ?項(xiàng)目需求
紅包總金額為money(元),分發(fā)份數(shù)為n,程序自動(dòng)完成紅包金額分配;要保證每一個(gè)紅包都有錢(qián),每一個(gè)紅包金額至少為1分錢(qián),所有紅包金額之和必須與總金額money相等;紅包生成后由軟件展示每個(gè)紅包的金額。效果圖如圖1所示。
2.3 ?數(shù)據(jù)類(lèi)型
在整個(gè)C語(yǔ)言學(xué)習(xí)過(guò)程中,我們接觸到的數(shù)據(jù)類(lèi)型有int、float、double、char;在本案例中,我們會(huì)用到int和double數(shù)據(jù)類(lèi)型。紅包總金額以元為單位,帶小數(shù)點(diǎn),需要用到double類(lèi)型的數(shù)據(jù);搶到紅包的最小金額為1分錢(qián),以分為單位就是整型數(shù);n個(gè)紅包,應(yīng)該采用整型數(shù)組。
2.4 ?涉及的知識(shí)點(diǎn)
實(shí)現(xiàn)這個(gè)程序,需要用到C語(yǔ)言基礎(chǔ)知識(shí),所涉及到的知識(shí)點(diǎn)有以下幾點(diǎn):
(1)變量的聲明,賦值和引用。
(2)整型數(shù)組的聲明,賦值和引用。
(3)輸入輸出函數(shù)的使用。
(4)數(shù)據(jù)類(lèi)型的隱式轉(zhuǎn)換和強(qiáng)制轉(zhuǎn)換。
(5)if-else語(yǔ)法結(jié)構(gòu)的使用。
(6)for循環(huán)結(jié)構(gòu)的使用及數(shù)組的遍歷。
(7)隨機(jī)數(shù)的獲取。
(8)stdlib.h和time.h頭文件的引入。
3 ?項(xiàng)目編碼
3.1 ?核心算法分析
在發(fā)第一個(gè)紅包時(shí),至少要保證給剩下的n-1個(gè)紅包留下n-1分錢(qián);第一個(gè)紅包的金額由系統(tǒng)在1到money*100-(n-1)之間隨機(jī);將獲得的隨機(jī)數(shù)賦值給紅包數(shù)組的第一個(gè)元素;然后能用來(lái)發(fā)紅包的金額更新為money*100減去第一個(gè)紅包金額之差;以此類(lèi)推,在發(fā)第i個(gè)紅包時(shí),要保證還沒(méi)有分發(fā)的紅包每個(gè)至少有1分錢(qián);第i個(gè)紅包的金額在1到money-(n-i)之間隨機(jī);最后一個(gè)紅包金額不用隨機(jī),將剩下的錢(qián)都給最后一個(gè)紅包。
計(jì)算機(jī)的隨機(jī)數(shù)是偽隨機(jī)數(shù),為使隨機(jī)算法得到的隨機(jī)值不重復(fù)實(shí)現(xiàn),需要用與時(shí)間相關(guān)的隨機(jī)種子,對(duì)隨機(jī)函數(shù)進(jìn)行初始化:srand((unsigned)time(NULL)),rand()返回的隨機(jī)數(shù)在[0,32 767]之間,要控制隨機(jī)數(shù)在1到n之間,rand()%n可以獲得0到n-1之間的隨機(jī)數(shù),rand()%n+1剛好可以獲得1到n之間的隨機(jī)數(shù)。
多次產(chǎn)生隨機(jī)數(shù),需要用到循環(huán)結(jié)構(gòu),while循環(huán)、do-while循環(huán)、for循環(huán)都可以實(shí)現(xiàn)本案例,結(jié)合幾個(gè)循環(huán)的特點(diǎn),對(duì)于已知循環(huán)次數(shù)采用for循環(huán)比較簡(jiǎn)潔。每次產(chǎn)生隨機(jī)金額之前,需要給剩下的還未生成的紅包每個(gè)至少留1分錢(qián),在留足余額后的金額里再進(jìn)行隨機(jī),并且隨機(jī)出的金額最少是1分錢(qián),最多是提留后所有的金額;因此隨機(jī)第i個(gè)紅包需要留下n-(i+1)分,產(chǎn)生的隨機(jī)數(shù)是[0,m-n+i+1]的閉區(qū)間,隨機(jī)的錢(qián)是隨機(jī)數(shù)加1分,所以bags[i]=rand()%(m-n+1+i)+1;最后一個(gè)紅包金額不需要用隨機(jī)數(shù)產(chǎn)生,直接將余額分發(fā)給最后一個(gè)紅包即可。
3.2 ?完整代碼
#include
#include
#include
void main()
{
double money;//以元為單位的金額;
int I,m,n,bags[1000];//m是以分為單位的金額,n是紅包總個(gè)數(shù);
srand((unsigned)time(NULL));//對(duì)時(shí)間函數(shù)進(jìn)行初始化;
printf("請(qǐng)輸入紅包總金額:");
scanf("%lf",&money);
printf("請(qǐng)輸入紅包總個(gè)數(shù):");
scanf("%d",&n);
m=(int)(money*100);//以元為單位的帶小數(shù)的金額轉(zhuǎn)換以分為單位的整型數(shù);
for(i=0;i { if(i==n-1)bags[i]=m;//如果是最后一個(gè)紅包,把剩余的錢(qián)給最后一個(gè)紅包; else bags[i]= rand()%(m-n+1+i)+1;//非最后一個(gè)紅包留好余額后隨機(jī); m=m-bags[i];//更新剩余的金額; } for(i=0;i { printf("%。2lf\t",bags[i]/100.0); } } 3.3 ?算法存在的問(wèn)題 隨著逐個(gè)紅包的生成,隨機(jī)數(shù)的范圍會(huì)逐步變窄;按照概率來(lái)說(shuō),最先隨機(jī)得到的紅包金額會(huì)比較大,后面隨機(jī)產(chǎn)生的紅包金額會(huì)逐漸變小;這跟我們平時(shí)搶的QQ紅包,微信紅包不一樣;該算法充分體現(xiàn)了一個(gè)“搶”字,“先下手為強(qiáng)”。 程序的功能是按照需求設(shè)計(jì)的,如果覺(jué)得上述案例算法不妥,可以根據(jù)需求修改算法;例如,多聲明一組數(shù)組list,將list數(shù)組所有元素的初始值都設(shè)置為-1,循環(huán)n次產(chǎn)生n個(gè)0到n-1之間不重復(fù)的隨機(jī)數(shù),依次保存在這個(gè)list數(shù)組中,然后遍歷list數(shù)組,將list數(shù)組各元素的值作為紅包數(shù)組的下標(biāo),因?yàn)檫@個(gè)下標(biāo)是隨機(jī)的,這樣就按照隨機(jī)算法不按順序輸出紅包數(shù)組里各元素,最終結(jié)果就可以避免之前先生成的紅包大后生成的紅包小的問(wèn)題。當(dāng)然,不同的編程人員可以按照自己的理解用其他不同的算法來(lái)實(shí)現(xiàn)程序需求。 4 ?結(jié) ?論 本項(xiàng)目案例非常生活化,實(shí)現(xiàn)的技術(shù)中用到了變量的聲明、賦值和引用;整型數(shù)組的聲明、賦值和引用;輸入輸出函數(shù)的使用;數(shù)據(jù)類(lèi)型的隱式轉(zhuǎn)換和強(qiáng)制轉(zhuǎn)換;if-else語(yǔ)法結(jié)構(gòu)的使用;for循環(huán)結(jié)構(gòu)的使用及數(shù)組的遍歷;隨機(jī)數(shù)的獲取?!癈語(yǔ)言程序設(shè)計(jì)”課程旨在引導(dǎo)學(xué)生理解和運(yùn)用C語(yǔ)言的基本語(yǔ)法,建立最基本的邏輯思維,為學(xué)習(xí)后續(xù)的軟件開(kāi)發(fā)課程奠定一個(gè)良好且穩(wěn)固的基礎(chǔ);該項(xiàng)目的實(shí)現(xiàn)過(guò)程引導(dǎo)學(xué)生溫習(xí)了C程序設(shè)計(jì)的基礎(chǔ)知識(shí),在編碼過(guò)程中又對(duì)知識(shí)進(jìn)一步強(qiáng)化,另外還擴(kuò)展了C語(yǔ)言中取隨機(jī)數(shù)的知識(shí),讓學(xué)生對(duì)知識(shí)的掌握有了進(jìn)一步的提升。 該案例將復(fù)雜問(wèn)題簡(jiǎn)化,從而激發(fā)學(xué)生學(xué)習(xí)編程的興趣,增強(qiáng)了編程的樂(lè)趣,提高學(xué)生解決實(shí)際問(wèn)題的能力,可以算得上C語(yǔ)言程序教學(xué)課程的一個(gè)經(jīng)典案例。 參考文獻(xiàn): [1] 譚浩強(qiáng).C程序設(shè)計(jì)(第5版) [M].北京:清華大學(xué)出版社,2017. [2] 本·克萊蒙.C程序設(shè)計(jì)新思維(第2版) [M].趙巖,譯.北京:人民郵電出版社,2018. [3] 王亮.《C語(yǔ)言程序設(shè)計(jì)》循環(huán)結(jié)構(gòu)教學(xué)案例研究 [J].科技視界,2018(1):60-61. 作者簡(jiǎn)介:紀(jì)輝進(jìn)(1977-),男,漢族,湖北黃陂人,講師,本科,主要研究方向:軟件技術(shù)教學(xué)。