何海燕

摘 要:該文主要對程序設(shè)計課程中的連乘算法進行教學設(shè)計,結(jié)合實例介紹了連乘算法的關(guān)鍵點,對算法中經(jīng)常會遇到的內(nèi)存溢出問題進行解析,針對連乘算法的通用表達式進行了優(yōu)化,使程序更易理解,達到加深理解,優(yōu)化教學效果。
關(guān)鍵詞:程序設(shè)計 算法 連乘算法 溢出
中圖分類號:G64 文獻標識碼:A 文章編號:1672-3791(2015)12(a)-0220-02
在程序設(shè)計課程中,算法是課程的重點,同時也是難點,如何將算法原理向?qū)W生講解透徹并可以讓其輕松接受,是在教學過程中需要思考的一個問題。
在計算機中,算法(Algorithm)是對特定問題求解步驟的一種描述,它是指令序列的集合。程序設(shè)計就是設(shè)計算法、編寫代碼、調(diào)試運行的過程。顯而易見,算法是程序設(shè)計的基礎(chǔ),程序設(shè)計是算法的具體實現(xiàn)。在程序設(shè)計課程的教學設(shè)計過程中,常用算法一般包括求最大/最小值、累加/連乘、窮舉法、遞推法等,該文將主要針對連乘算法進行分析。
1 連乘算法
在程序基礎(chǔ)教學中,為了提高教學效果,針對剛?cè)腴T的程序設(shè)計初學者,教師們一般采用任務(wù)驅(qū)動法[1]進行算法的分析,引導(dǎo)學生理解和掌握該算法的核心思想,進而再用程序的方式來描述與驗證該算法。例如:
以上是一個典型的連乘算法,該算法描述的關(guān)鍵點可歸納如下:
(1)每一項和每次連乘之積是變化量。
(2)因此,需要兩個變量:
①用T表示每一項的值:T=T+1。
②用S表示連乘之積:S=S*T。
(3)循環(huán)終止條件: 循環(huán)次數(shù)>n。
(4)初始化:S=1 。
2 內(nèi)存溢出問題
在講解程序算法時,大多數(shù)程序設(shè)計教程都很少提及賦值或計算中的“溢出”問題,然而在學生的編程操作中,“溢出”卻是經(jīng)常會遇到的一個問題[2],這些問題常常會讓學生覺得困惑,查找原因時卻無從下手,導(dǎo)致學生出現(xiàn)畏難情緒。因此,教師有必要在授課過程中,對程序在內(nèi)存中的存儲方式進行初步講解,讓學生可以了解程序的運行機制,加深理解。
軟件在運行過程中,如果程序調(diào)用的數(shù)據(jù)文件過大,或程序設(shè)計中存在著死循環(huán)等bug,軟件寫入內(nèi)存中的數(shù)據(jù)量超過了系統(tǒng)分配給該軟件的內(nèi)存空間大小,則會發(fā)生內(nèi)存空間裝不下而溢出的現(xiàn)象,這種現(xiàn)象就叫內(nèi)存溢出。在求階乘的算法中,由于階乘的結(jié)果累積速度較快較大,容易發(fā)生數(shù)據(jù)溢出。
讓學生進行程序的調(diào)試與運行,當n=10和=50時運行結(jié)果如圖1所示,但當n=100時,卻彈出如圖2所示的警告信息。
分析導(dǎo)致“溢出”錯誤的原因:
當程序運行發(fā)生“溢出”錯誤時,通過調(diào)試跟蹤,在T=(2* i) ^ 2/((2*i-1)*(2*i+1))語句處,把光標移至i變量上,可以發(fā)現(xiàn)溢出時i的值為91;當i=91時,表達式((2*i-1)*(2*i+1))=<溢出>,該表達式的值為33123。程序?qū)⒔Y(jié)果值S設(shè)置為double類型,當i=91時,結(jié)果為33123,這個值按道理應(yīng)在double類型的數(shù)值范圍內(nèi),但程序仍然發(fā)生了溢出錯誤,問題在哪里呢?
實際上,產(chǎn)生這個溢出問題的原因是由于VB本身的內(nèi)存分配機制造成的,VB在進行計算過程中,它總是分配一個最省內(nèi)存的臨時內(nèi)存空間去存儲這些中間計算結(jié)果數(shù)值,這個最省的內(nèi)存空間容量根據(jù)表達式中數(shù)據(jù)類型決定,如上述相乘的兩個表達式(2*i-1)和(2*i+1),他們當中的變量i是整型,因此,VB也將使用一個類型為整型的臨時變量來存儲兩個表達式的乘積。所以,當i=91時,得到乘積結(jié)果33 123,此時即使是乘積結(jié)果變量S設(shè)置為double類型,但乘積結(jié)果(33 123)已超過了聲明為整型的臨時變量空間的極限(-32 768~+32 767),所以仍然會發(fā)生溢出錯誤。
根據(jù)上面的原因分析,可以從以下幾方面進行修正:
(1)將變量 i 定義為長整型或?qū)崝?shù)型或變體型。
(2)將錯誤語句中的變量 i或常量(1或2)其一操作數(shù)利用轉(zhuǎn)換函數(shù)Clng(i)或Clng(1),以求足以容納計算結(jié)果。
(3)避免大數(shù)相乘,可將錯誤語句改為T=(2*i)^ 2/(2*i - 1)/(2*i+1)。
(4)連乘算法的改進。
同一問題可用不同算法解決,而一個算法的質(zhì)量優(yōu)劣將影響到算法乃至程序的效率。雖然上述方法解決了“溢出”問題,但是表達式T=(2*i)^2/(2*i-1)*(2*i+1)顯得很笨重,表達式明顯復(fù)雜。能否有辦法可以降低復(fù)雜度,簡化表達式以求程序優(yōu)化呢?
可以把通項表達式T=(2*i)^2/(2*i-1)*(2*i+1)中的分子式分解開來,把問題理解為簡單表達式T=A/B(其中A=(2*i)^2和B=(2*i-1)*(2*i+1),如此一來問題就變得較為簡單且易于解決。因此,求∏的近似值的VB程序代碼優(yōu)化實現(xiàn)如下:
在此例中,關(guān)鍵點在于如何將復(fù)雜的通項表達式分解為簡單表達式,進而實現(xiàn)連乘算法的優(yōu)化。因此,如何構(gòu)造通項表達式尤為關(guān)鍵,必須注意2點。
(1)通項表達式T=B/A中的A或B均可為常量或變量表達式,A和B可以繼續(xù)分解;①若A=1, 則T=B;②若B=1, 則T=1/A;
(2)必須精選變量A與B的數(shù)據(jù)類型,避免出現(xiàn)“溢出”。
3 結(jié)語
該文對程序設(shè)計課程中關(guān)于連乘算法的問題進行了初步探討,指出程序設(shè)計初學者中學習過程中經(jīng)常會遇到的“溢出”問題,提出修正方法,并對連乘算法進行改進優(yōu)化,加深理解,強化教學效果。
參考文獻
[1] 楊晨霞,涂風濤.任務(wù)驅(qū)動教學法在Visual Basic程序設(shè)計教學中的應(yīng)用[J].職教論壇,2012(18):79-81.
[2] 賈穎.“VB 程序設(shè)計”課程教學中的變量類型使用問題研究[J].Computer Education,2008(20):138-139.