摘 要 循環(huán)結(jié)構(gòu)是結(jié)構(gòu)化程序設(shè)計(jì)中的三種基本結(jié)構(gòu)之一,也是程序設(shè)計(jì)的基礎(chǔ)。但是,對(duì)于初學(xué)者來說,循環(huán)結(jié)構(gòu)與人類日常的思維習(xí)慣不同,較難掌握。本文用幾個(gè)例子闡述了在《C語言程序設(shè)計(jì)》課程中循環(huán)結(jié)構(gòu)的教學(xué)方法,這些方法在日常授課中取得了較好的效果。
關(guān)鍵詞 C語言;結(jié)構(gòu)化程序設(shè)計(jì);循環(huán)結(jié)構(gòu);效率
1 引言
順序、分支、循環(huán)是結(jié)構(gòu)化程序設(shè)計(jì)的三種基本結(jié)構(gòu),所以在高級(jí)語言程序設(shè)計(jì)課程中,掌握這三種結(jié)構(gòu)是學(xué)好程序設(shè)計(jì)的基礎(chǔ)。而循環(huán)結(jié)構(gòu)是這三者中最復(fù)雜的一種結(jié)構(gòu),幾乎所有的程序都離不開循環(huán)結(jié)構(gòu)。在C語言中,循環(huán)結(jié)構(gòu)主要是由for和while、do-while語句實(shí)現(xiàn)的,其中for語句的應(yīng)用更為普遍一些。for語句的用法對(duì)于有程序設(shè)計(jì)經(jīng)驗(yàn)的學(xué)生來說輕而易舉,但是對(duì)于那些沒有經(jīng)驗(yàn)的初學(xué)者來說,難度卻不小。本文從初學(xué)者的角度,闡述了C語言中循環(huán)結(jié)構(gòu)幾種典型應(yīng)用的實(shí)現(xiàn)方法。
2 用循環(huán)結(jié)構(gòu)輸出幾何圖形
輸出簡單的幾何圖形(如圖1),是循環(huán)結(jié)構(gòu)的典型應(yīng)用之一。對(duì)于這一類型的題目,初學(xué)者往往直接采用一條或若干條輸出語句printf完成,這樣雖然可以完成題目要求,但是很顯然缺乏靈活性,不符合程序設(shè)計(jì)的思想。按照正常的程序設(shè)計(jì)思想,應(yīng)該先分析圖形的構(gòu)成,找出其中的規(guī)律:如圖1(a)中的實(shí)心三角形,每一行由若干個(gè)空格、星號(hào)和一個(gè)回車換行符構(gòu)成,將行號(hào)、空格數(shù)和星號(hào)數(shù)分別設(shè)為i、m和n,則可以形成下表:
表1 實(shí)心三角形的構(gòu)成表
行號(hào)i | 空格數(shù)m | 星號(hào)數(shù)n |
1 | 4 | 1 |
2 | 3 | 3 |
3 | 2 | 5 |
4 | 1 | 7 |
5 | 0 | 9 |
分析表1,可以得出行號(hào)i與空格數(shù)m、星號(hào)數(shù)n如下的數(shù)學(xué)關(guān)系:
m=5-i,n=2×i-1
則實(shí)心三角形的構(gòu)成規(guī)律可以描述為:第i行由(5-i)個(gè)空格和(2×i-1)個(gè)星號(hào)和一個(gè)回車符構(gòu)成。把行號(hào)i作為for語句的循環(huán)變量,輸出圖形程序的主要部分見程序段1。
采用上面的方法,可以使學(xué)生很容易編寫出類似的程序,其中的關(guān)鍵在于讓學(xué)生找出圖形中行號(hào)與每一行的空格數(shù)以及星號(hào)數(shù)的關(guān)系(對(duì)于圖1(b)、(c)需要把圖形分成幾個(gè)部分,再分析其中的構(gòu)成規(guī)律),這需要學(xué)生數(shù)學(xué)方面的知識(shí),非編程本身的范疇了。
for(i=1;i<=5;i++) { /*輸出(5-i)個(gè)空格;*/ for(m=1;m<=5-i;m++) printf(“ ”); /*輸出(2*i-1)個(gè)星號(hào);*/ for(n=1;n<=2*i-1;n++) printf(“*”); /*輸出回車符;*/ printf(“\n”); } 程序段1 實(shí)心三角形的主要程序 |
3 數(shù)組中循環(huán)結(jié)構(gòu)的應(yīng)用
在C語言中,for語句經(jīng)常與數(shù)組相結(jié)合,用于實(shí)現(xiàn)數(shù)組元素的賦值、輸入與輸出。對(duì)于初學(xué)者來說,更習(xí)慣于用順序結(jié)構(gòu)的語句來實(shí)現(xiàn)(如圖2左)。我們將圖2左的幾條語句作比較,可以看出在這5條語句中,不同的只有數(shù)組下標(biāo),那么就可以將這5條語句合并成一條for語句,將數(shù)組下標(biāo)換成for語句的循環(huán)變量i,而i的值從0增加到 4。按照for語句的基本語法規(guī)則可以很容易的寫出圖2右的for語句。
同樣,對(duì)于下面這個(gè)輸出二維數(shù)組元素的例子,也可以用上述辦法實(shí)現(xiàn),不過轉(zhuǎn)換過程比上例要復(fù)雜一些:經(jīng)過對(duì)比圖3左側(cè)方框中順序結(jié)構(gòu)的12條語句,可以發(fā)現(xiàn)也是只有數(shù)組下標(biāo)在變化,但是由于是二維數(shù)組,行下標(biāo)和列下標(biāo)同時(shí)都在變化,很顯然不能直接用一條簡單的for語句來實(shí)現(xiàn)(不是絕對(duì)不可以實(shí)現(xiàn),后面將會(huì)看到)。但是我們可以把這12條語句細(xì)分一下,3條語句為一組,而在同一組中的語句只有列下標(biāo)在變化,這時(shí)可以采用上例中的方法,將列下標(biāo)都用循環(huán)變量j來代替,得到圖3右上的形式。再次對(duì)比圖3右上的4條for語句,不同的是行下標(biāo),同樣用新的循環(huán)變量i來代替,合并后得到圖3右下最終二重for循環(huán)的語句。
在上例中,常規(guī)的思路都采用二重for循環(huán)與二維數(shù)組相結(jié)合來實(shí)現(xiàn)對(duì)數(shù)組元素的訪問,實(shí)際上也可以使用一重for循環(huán)來實(shí)現(xiàn):無論如何變化,我們可以先確定的是,輸出語句printf肯定要執(zhí)行12次,如果用一重for循環(huán),那么循環(huán)變量i的值就要從0遞增到11。再分析數(shù)組行下標(biāo)m和列下標(biāo)n與循環(huán)變量i之間的關(guān)系,很顯然:i=m*3+n,按照整數(shù)除法的思想,行下標(biāo)m恰好是循環(huán)變量i整除3后的商,而列下標(biāo)n恰好是循環(huán)變量i整除3后的余數(shù),即:
m=i/3,n=i%3
從而可以寫出下面的for語句:
for(i=0;i<12;i++)
printf(“%d”,a[i/3][i%3]);
4 循環(huán)結(jié)構(gòu)中的效率問題
對(duì)于程序設(shè)計(jì)的初學(xué)者來說,往往以完成題目要求的功能為目的,程序的執(zhí)行效率是最容易忽略的一個(gè)問題。在循環(huán)結(jié)構(gòu)中,具體表現(xiàn)為循環(huán)體的執(zhí)行次數(shù)。例如,一個(gè)經(jīng)典的素?cái)?shù)判定問題。在數(shù)學(xué)中素?cái)?shù)如下定義:素?cái)?shù)即指那些大于1,且除了1和它本身外,不能被其它任何數(shù)整除的數(shù)。根據(jù)這一定義,初學(xué)者很容易編寫出如下程序段2的程序:
int isprime(int n) { int i; for(i=2;i<n;i++) if(n%i==0) return 0; return 1; } 程序段2 判斷素?cái)?shù)的程序段 |
上面的程序,完全可以實(shí)現(xiàn)題目要求的功能,初學(xué)者往往滿足于此。但是當(dāng)對(duì)for循環(huán)的執(zhí)行次數(shù)進(jìn)行分析時(shí),我們發(fā)現(xiàn):當(dāng)n不是素?cái)?shù)時(shí),沒有任何問題;而當(dāng) n是素?cái)?shù)時(shí),循環(huán)體就要執(zhí)行(n-2)次,而實(shí)際上是不需要這么多次的。根據(jù)數(shù)學(xué)的知識(shí),可以將次數(shù)降為n/2或n的算術(shù)平方根,這樣可以大大減少循環(huán)體的執(zhí)行次數(shù),提高程序的效率。
程序的執(zhí)行效率是編程中時(shí)刻需要考慮的問題,也是程序設(shè)計(jì)中的基本要求。這需要許多算法方面的知識(shí),對(duì)于初學(xué)者來說,要求可能過高,但是我們?cè)谥v授過程中要注意向?qū)W生灌輸這種思想,從學(xué)習(xí)之初就要打下良好的基礎(chǔ),尤其是類似上面例子中這樣顯而易見的情況,可以提醒學(xué)生在編制完一道程序以后,檢驗(yàn)一下,是否還有可優(yōu)化的地方,這對(duì)以后進(jìn)一步高級(jí)編程的學(xué)習(xí)都是必要的。
5 結(jié)束語
以上這些,都是本人在授課過程中的一些體會(huì),可能比較膚淺,但是從初學(xué)者的角度來看,卻是必要的。如何讓一名初學(xué)者盡快擺脫日常的思維定式,更加透徹地理解和掌握程序設(shè)計(jì)中的基本思想,領(lǐng)會(huì)程序設(shè)計(jì)的精髓,是高級(jí)語言程序設(shè)計(jì)這門課程在講授過程中,應(yīng)該時(shí)刻注意的問題。希望本文能在這方面起到一點(diǎn)作用,同時(shí)望廣大同仁多多指教。
參考文獻(xiàn)
[1] 譚浩強(qiáng). C 語言程序設(shè)計(jì)(第二版)[M]. 北京:清華大學(xué)出版社,1999
[2] 蘇運(yùn)霖譯. 計(jì)算機(jī)程序設(shè)計(jì)藝術(shù)第1 卷 基本算法[M]. 北京:國防工業(yè)出版社,2002