第5講 結(jié)構(gòu)化程序設(shè)計(jì)之流程控制語句_第1頁
第5講 結(jié)構(gòu)化程序設(shè)計(jì)之流程控制語句_第2頁
第5講 結(jié)構(gòu)化程序設(shè)計(jì)之流程控制語句_第3頁
第5講 結(jié)構(gòu)化程序設(shè)計(jì)之流程控制語句_第4頁
第5講 結(jié)構(gòu)化程序設(shè)計(jì)之流程控制語句_第5頁
已閱讀5頁,還剩52頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、河北能源職業(yè)技術(shù)學(xué)院教案第5講 結(jié)構(gòu)化程序設(shè)計(jì)之流程控制語句教學(xué)過程設(shè)計(jì)一 新課引入 默認(rèn)情況下程序是順序執(zhí)行的。當(dāng)程序員在編寫程序時(shí)并不知道在一次具體執(zhí)行中執(zhí)行者會做些什么時(shí),他可以建立一個(gè)執(zhí)行者用以作出判定的標(biāo)準(zhǔn)。例如:“朋友來了,端出好酒;豺狼來了,拿出獵槍?!?。有時(shí)程序的某部分可能需要執(zhí)行多次。例如:在中草藥炮制過程中,對某種藥材要經(jīng)過“九蒸九曬”才符合要求,這種重復(fù)必須指明重復(fù)的次數(shù)。有時(shí)重復(fù)執(zhí)行程序的某部分不一定有明確的次數(shù),但可以以是否達(dá)到某個(gè)目標(biāo)作為重復(fù)終止的判斷依據(jù)。例如:在把假分?jǐn)?shù)化成真分?jǐn)?shù)時(shí),可以從分子中不斷地減去分母,直到分子小于分母為止。 操作之間的關(guān)系操作流程包括:

2、順序、選擇、循環(huán)、轉(zhuǎn)向(語言表達(dá)所需要的)。其中順序、選擇、循環(huán)是三種基本結(jié)構(gòu),已經(jīng)證明,由這三種基本結(jié)構(gòu)組成的程序結(jié)構(gòu),可以解決任何復(fù)雜的問題。由基本結(jié)構(gòu)所構(gòu)成的程序是結(jié)構(gòu)化的程序,它不存在無規(guī)律的轉(zhuǎn)向,只在本基本結(jié)構(gòu)內(nèi)才允許存在分支和向前或向后的跳轉(zhuǎn)。軟件工程提倡程序員書寫結(jié)構(gòu)化的程序。 C語言提供的流程控制語句有描述“選擇”的語句有:if語句、switch語句;描述“循環(huán)”的語句有:while語句、do-while語句、for語句;描述“轉(zhuǎn)向”的語句有:goto語句、break語句、continue語句、return語句。為了達(dá)到直觀形象、易于理解的效果,我們在進(jìn)行結(jié)構(gòu)化編程的同時(shí)可以輔

3、助以一種圖形工具結(jié)構(gòu)化的流程圖。 本講將主要介紹關(guān)于四種操作流程:順序、選擇、循環(huán)、轉(zhuǎn)向的C語言描述、圖形描述方法,以及由三種基本結(jié)構(gòu)所構(gòu)成的結(jié)構(gòu)化的程序。二 講授新課1 順序默認(rèn)情況下程序是順序執(zhí)行的,所以C語言沒有必要提供相關(guān)的描述語句來表示。2 選擇當(dāng)程序員在編寫程序時(shí)并不知道在一次具體執(zhí)行中執(zhí)行者會做些什么時(shí),他可以建立一個(gè)執(zhí)行者用以作出判定的標(biāo)準(zhǔn)。例如:“朋友來了,端出好酒;豺狼來了,拿出獵槍?!?。C語言提供的描述“選擇”的語句有:if語句、switch語句。 if語句1. if語句的兩種形式C語言提供了兩種形式的if語句: 單分支選擇if語句if(“條件”表達(dá)式本講中的“條件”表達(dá)

4、式指的是其結(jié)果值要么為1,要么為0。)語句 說明: “條件”表達(dá)式的類型不限于邏輯表達(dá)式,可以是任意的數(shù)值類型(包括整型、實(shí)型、字符型、指針型數(shù)據(jù))。 在if和else后面可以只有一個(gè)操作語句,也可以有多個(gè)操作語句,此時(shí)需用花括號“”將幾個(gè)語句括起來成為一個(gè)復(fù)合語句。 單分支選擇if語句的流程圖表示如下圖所示。 單分支選擇if語句的執(zhí)行過程是:求“條件”表達(dá)式的值。如果“條件”表達(dá)式的值為真,則執(zhí)行“語句”,否則不執(zhí)行“語句”。 單分支選擇if語句的功能是:判定所指定的條件是否滿足,根據(jù)判定的結(jié)果(真或假)決定是否執(zhí)行給定的一組操作。 雙分支選擇if語句if(“條件”表達(dá)式)語句1else語句

5、2說明同上。 雙分支選擇if語句的流程圖表示如下圖所示。 雙分支選擇if語句的執(zhí)行過程是:求“條件”表達(dá)式的值。如果“條件”表達(dá)式的值為真,則執(zhí)行“語句1”,否則執(zhí)行“語句2”。 雙分支選擇if語句的功能是:判定所指定的條件是否滿足,根據(jù)判定的結(jié)果(真或假)決定執(zhí)行給定的兩組操作其一。2. if語句的嵌套嵌套的if語句能實(shí)現(xiàn)多分支選擇。在if語句中又包含一個(gè)或多個(gè)if語句稱為if語句的嵌套。例如:if(“條件”表達(dá)式) if(“條件”表達(dá)式)語句1else語句2elseif(“條件”表達(dá)式)語句3else語句4應(yīng)當(dāng)注意if與else默認(rèn)的配對關(guān)系else總是與其前面最近的if配對。因此最好使內(nèi)

6、嵌if語句也包含else部分,這樣if與else的數(shù)目相同,從內(nèi)層到外層一一對應(yīng),不致出錯。如果if與else的數(shù)目不同,要改變這種默認(rèn)的配對關(guān)系,可以加花括弧來確定配對關(guān)系。例如:if(“條件”表達(dá)式)if(“條件”表達(dá)式)語句1else語句2這時(shí) 限定了內(nèi)嵌if語句的范圍,因此else與第一個(gè)if配對。常用的一種嵌套形式是:if(“條件”表達(dá)式1)語句1else if(“條件”表達(dá)式2)語句2 else if(“條件”表達(dá)式n)語句nelse語句n+1說明同上。 其流程圖表示如下圖所示。 其執(zhí)行過程是:求“條件”表達(dá)式1的值,如果“條件”表達(dá)式1的值為真,則執(zhí)行“語句1”,否則求“條件”表

7、達(dá)式2的值,如果“條件”表達(dá)式2的值為真,則執(zhí)行“語句2”,否則,依此類推。當(dāng)出現(xiàn)某個(gè)“條件”表達(dá)式的值為真時(shí),則執(zhí)行其對應(yīng)的語句。如果所有的“條件”表達(dá)式的值均為假,則執(zhí)行“語句n+1”。其功能是:多次判斷。每判斷一步,都分別分離出一些范圍(這些范圍已能用于作出相應(yīng)的結(jié)論),逐步縮小判定的范圍,直到不必再縮小判定的范圍就可以作出相應(yīng)的結(jié)論。 switch語句我們可以用嵌套的if語句來實(shí)現(xiàn)多分支選擇,但如果分支越多,則多嵌套的if語句的層數(shù)就越多,程序冗長而且可讀性降低。某些時(shí)候,在使用嵌套的if語句時(shí),所有的分支看起來都非常相似,因?yàn)樗鼈兌荚趯σ粋€(gè)完全相同的“條件”表達(dá)式(“條件”表達(dá)式的類

8、型只能為整型、字符型或枚舉型)進(jìn)行求值,惟一的區(qū)別是每個(gè)分支都將“條件”表達(dá)式的值與一個(gè)不同的值(也相應(yīng)地只能為整型、字符型或枚舉型)進(jìn)行比較。例如: if (day = = 0)dayName = Sunday;else if (day = = 1)dayName = Monday;else if (day = = 2)dayName = Tuesday;else if (day = = 3).elsedayName = Unknown; 在這些情況下,通常需要將嵌套的if語句改寫為一個(gè)使用break語句的switch語句,使程序更簡潔、更易懂。switch語句的一般形式如下:switch(

9、“條件”表達(dá)式)case 常量表達(dá)式1:語句1case 常量表達(dá)式2:語句2case 常量表達(dá)式n:語句ndefault:語句n+1其流程圖表示如下圖所示。說明: switch后面括號中的“條件”表達(dá)式的類型只能為整型、字符型或枚舉型。 每一個(gè)case后面都需要一個(gè)常量表達(dá)式(例如:1、a、3+4),且該常量表達(dá)式的值的類型要與switch后面括號中的“條件”表達(dá)式的值的類型相匹配。 每一個(gè)case后面的常量表達(dá)式的值必須互不相同,否則就會出現(xiàn)邏輯上互相矛盾的現(xiàn)象對switch后面括號中的“條件”表達(dá)式的同一個(gè)值,有兩種或多種執(zhí)行方案。 一個(gè)switch語句中可以沒有default標(biāo)號或只能有

10、一個(gè)default標(biāo)號,default標(biāo)號表示不是任何case標(biāo)號所提供的其他情況。 default標(biāo)號和各個(gè)case標(biāo)號之間無先后順序。 多個(gè)case標(biāo)號可以共用一組執(zhí)行語句。例如:case A:case B:case C:printf(60n);break;grade的值為A、B或C時(shí)都執(zhí)行同一組語句。 switch后面括號中的“條件”表達(dá)式實(shí)際上并非進(jìn)行真正的條件判斷,而只是一種跳轉(zhuǎn)指示(與 if 語句不同),表示下面應(yīng)該跳轉(zhuǎn)到什么位置繼續(xù)執(zhí)行。而各個(gè)“case常量表達(dá)式”和default實(shí)際上只是一個(gè)語句標(biāo)號,并不是在該處進(jìn)行條件判斷。執(zhí)行時(shí)根據(jù)switch后面括號中的“條件”表達(dá)式的

11、值找到匹配的入口標(biāo)號,就跳轉(zhuǎn)到此標(biāo)號后面的語句處,并從此語句開始執(zhí)行下去,而不再通過判斷來決定是否繼續(xù)執(zhí)行即執(zhí)行完一個(gè)標(biāo)號后面的語句后,流程控制轉(zhuǎn)移到下一個(gè)標(biāo)號后面的語句繼續(xù)執(zhí)行,直到整個(gè)switch語句結(jié)束(即遇到“”)。在標(biāo)號后面雖然包含一個(gè)以上執(zhí)行語句,但可以不必用花括號括起來,會自動順序執(zhí)行本標(biāo)號后面所有的執(zhí)行語句。當(dāng)然加上花括號也可以。如果要在執(zhí)行一個(gè)標(biāo)號后面的語句組后使流程跳出switch語句,必須在其語句組最后加上break語句,最后一個(gè)標(biāo)號可以不加break語句。使用break語句的switch語句的一般形式如下:switch(“條件”表達(dá)式)case 常量表達(dá)式1:語句1 b

12、reak;case 常量表達(dá)式2:語句2 break;case 常量表達(dá)式n:語句n break;default:語句n+1 (break;)其流程圖表示如下圖所示。 switch語句的執(zhí)行過程:首先計(jì)算switch后面括號中“條件”表達(dá)式的值(switch后面括號中的“條件”表達(dá)式只求值一次。),然后在作為具體的復(fù)合語句中的語句序列中從前開始查找?guī)ase標(biāo)號的帶標(biāo)號語句。如果某個(gè)帶case標(biāo)號的帶標(biāo)號語句中case后常量表達(dá)式的值與所求得的“條件”表達(dá)式的值相同,那么就從該帶標(biāo)號語句開始往后執(zhí)行,直到遇到break等語句退出該switch語句或執(zhí)行到該復(fù)合語句末尾(執(zhí)行到右花括號“”處。)

13、。如果沒有一個(gè)帶標(biāo)號語句中case后常量表達(dá)式的值與所求得的“條件”表達(dá)式的值相同,那么就接著查找其后有無帶default標(biāo)號的帶標(biāo)號語句。若有,則從default標(biāo)號所標(biāo)記的語句往后執(zhí)行,直到執(zhí)行到該復(fù)合語句末尾或遇到break等語句退出本switch語句;否則,不執(zhí)行該復(fù)合語句中任何語句,直接退出switch語句。 選擇結(jié)構(gòu)的嵌套 程序舉例【例】由用戶輸入某一年份,判斷該年份是否為閏年,并將判斷結(jié)果輸出到屏幕。分析:判斷某一年份為閏年的方法為: 能被4整除,但不能被100整除; 能被400整除。滿足以上兩個(gè)條件中的任何一個(gè)條件都是閏年,否則都是非閏年。至于如何得到這個(gè)判定定理,似乎不應(yīng)該問

14、程序員,更應(yīng)該去問天文學(xué)家! 繪制與閏年的判定定理功能等價(jià)的判定表: 分析以上判定定理中的條件,我們可以從其中提取出3個(gè)原子斷言: 能被4整除; 能被100整除; 能被400整除。理論上對于這3個(gè)原子斷言的真假有2*2*2=8個(gè)組合方式,如下表所示,下表中的書寫規(guī)律為表達(dá)式y(tǒng)ear%400= =0的值變化得最快,year%100= =0次之,year%4= =0的值變化得最慢:year%4= =0year%100= =0year%400= =0真真真真真假真假真真假假假真真假真假假假真假假假 但事實(shí)上,上表中有些情況根本不可能存在,具體情況及其原因如下表:year%4= =0year%100=

15、 =0year%400= =0真真真真真假真假真條件不可能同時(shí)成立真假假假真真條件不可能同時(shí)成立假真假條件不可能同時(shí)成立假假真條件不可能同時(shí)成立假假假 整理成下表:year%4= =0year%100= =0year%400= =0真真真真真假真假假假假假 再結(jié)合前面提到的閏年的判定定理,得到與閏年的判定定理功能等價(jià)的判定表,如下表所示:year%4= =0year%100= =0year%400= =0閏年真真真是真真假否真假假是假假假否 有了這個(gè)判定表,我們解題的思路就清晰了。下面的程序可供參考。參考程序1:一次判斷。main() int year; scanf(%d,&year); if

16、(year%4= =0)&(year%100!=0)|(year%400= =0) printf(%d is a leap year.n,year); else printf(%d is not a leap year.n,year);參考程序2:多次判斷。每判斷一步,都分別分離出一些范圍(這些范圍已能用于判定是閏年或非閏年),逐步縮小判定的范圍,直到不必再縮小判定的范圍就可以作出相應(yīng)的結(jié)論。main() int year; scanf(%d,&year); if(year%4= =0) if(year%100= =0) if(year%400= =0) printf(%d is a leap

17、 year.n,year); else printf(%d is not a leap year.n,year); else printf(%d is a leap year.n,year); else printf(%d is not a leap year.n,year);或main() int year; scanf(%d,&year); if(year%4!=0) printf(%d is not a leap year.n,year); else if(year%100!=0) printf(%d is a leap year.n,year); else if(year%400!=0

18、) printf(%d is not a leap year.n,year); else printf(%d is a leap year.n,year);3 循環(huán) 有時(shí)程序的某部分可能需要執(zhí)行多次。例如:在中草藥炮制過程中,對某種藥材要經(jīng)過“九蒸九曬”才符合要求,這種重復(fù)必須指明重復(fù)的次數(shù);有時(shí)重復(fù)執(zhí)行程序的某部分不一定有明確的次數(shù),但可以以是否達(dá)到某個(gè)目標(biāo)作為重復(fù)終止的判斷依據(jù)。例如:在把假分?jǐn)?shù)化成真分?jǐn)?shù)時(shí),可以從分子中不斷地減去分母,直到分子小于分母為止。常見的循環(huán)有兩種:循環(huán)次數(shù)可以確定;循環(huán)次數(shù)不能確定而只能給出循環(huán)結(jié)束條件。C語言提供的描述“循環(huán)”的語句有:while語句、do-w

19、hile語句、for語句。 while語句 while(“條件”表達(dá)式)循環(huán)體語句 說明: 循環(huán)體如果包含一個(gè)以上的語句,應(yīng)該用花括號括起來,以復(fù)合語句形式出現(xiàn)。如果不加花括號,則while語句的范圍只到while后面第一個(gè)分號處。 對于循環(huán)次數(shù)可以確定的循環(huán),循環(huán)控制變量初始化的操作應(yīng)在while語句之前完成。 對于循環(huán)次數(shù)可以確定的循環(huán),應(yīng)在while語句的循環(huán)體中包含使循環(huán)趨于結(jié)束的語句。例如:后面的例1中循環(huán)結(jié)束的條件是counter99,因此在循環(huán)體中應(yīng)該有使counter增值以最終導(dǎo)致counter99的語句,今用counter=counter+1;來達(dá)到此目的。如果無此語句,則c

20、ounter的值始終不改變,循環(huán)永不結(jié)束。 可以用break語句跳出本層while循環(huán),用continue語句結(jié)束本層、本次while循環(huán)。 while語句的流程圖表示如下圖所示。 while語句的執(zhí)行過程是:求“條件”表達(dá)式的值(即判斷給定的條件是否成立),如果“條件”表達(dá)式的值為真(即給定的條件成立),則執(zhí)行“循環(huán)體語句”。再求“條件”表達(dá)式的值,如果“條件”表達(dá)式的值仍為真,則再執(zhí)行“循環(huán)體語句”,如此反復(fù)執(zhí)行循環(huán)體語句,直到某一次“條件”表達(dá)式的值為假(即給定的條件不成立),此時(shí)退出while語句。 while語句的功能是:既可以實(shí)現(xiàn)循環(huán)次數(shù)可以確定的循環(huán),也可以實(shí)現(xiàn)循環(huán)次數(shù)不能確定的

21、循環(huán)。 do-while語句do循環(huán)體語句while(“條件”表達(dá)式);說明同上。do-while語句的流程圖表示如下圖所示。do-while語句的執(zhí)行過程是:先執(zhí)行一次“循環(huán)體語句”,然后求“條件”表達(dá)式的值(即判斷給定的條件是否成立),如果“條件”表達(dá)式的值為真(即給定的條件成立),則返回重新執(zhí)行“循環(huán)體語句”,然后再求“條件”表達(dá)式的值,如果“條件”表達(dá)式的值仍為真,則再返回重新執(zhí)行“循環(huán)體語句”,如此反復(fù)執(zhí)行循環(huán)體語句,直到“條件”表達(dá)式的值為假(即給定的條件不成立),此時(shí)退出do-while語句。do-while語句的功能是:既可以實(shí)現(xiàn)循環(huán)次數(shù)可以確定的循環(huán),也可以實(shí)現(xiàn)循環(huán)次數(shù)不能確

22、定的循環(huán)。 for語句for(表達(dá)式1;表達(dá)式2;表達(dá)式3)循環(huán)體語句 for語句表達(dá)循環(huán)次數(shù)可以確定的循環(huán)時(shí)的一般形式如下: for(循環(huán)控制變量賦初值;循環(huán)條件;循環(huán)變量增值)循環(huán)體語句 說明: “表達(dá)式1”可以省略,注意:省略“表達(dá)式1”時(shí),其后的分號不能省略。執(zhí)行時(shí),跳過求解“表達(dá)式1”這一步,其他不變。此時(shí)對于循環(huán)次數(shù)已經(jīng)確定的for語句,應(yīng)在for語句之前給循環(huán)控制變量賦初值。 “表達(dá)式2”可以省略,注意:省略“表達(dá)式2”時(shí),其后的分號不能省略。執(zhí)行時(shí),認(rèn)為“表達(dá)式2”的值始終為真,不在此處判斷循環(huán)條件,其他不變。此時(shí)應(yīng)在循環(huán)體中判斷循環(huán)條件,否則循環(huán)將無終止地進(jìn)行下去。 “表達(dá)式

23、3”可以省略。執(zhí)行時(shí),跳過求解“表達(dá)式3”這一步,其他不變。此時(shí)對于循環(huán)次數(shù)可以確定的循環(huán),應(yīng)在for語句的循環(huán)體中設(shè)置使循環(huán)趨向于結(jié)束的語句。對于循環(huán)次數(shù)可以確定的循環(huán),可以在for語句的循環(huán)體中包含使循環(huán)趨于結(jié)束的語句,也可以在表達(dá)式3中包含使循環(huán)趨于結(jié)束的操作。 可以省略“表達(dá)式1”和“表達(dá)式3”,只有“表達(dá)式2”,即只給出循環(huán)條件,在這種情況下,for語句完全等價(jià)于while語句。 3個(gè)表達(dá)式都可以省略,即:for(;)語句相當(dāng)于while(1)語句。 “表達(dá)式1”可以是設(shè)置循環(huán)控制變量初值的賦值表達(dá)式,也可以是與循環(huán)控制變量無關(guān)的其他表達(dá)式??梢栽凇氨磉_(dá)式3”中包含使循環(huán)趨于結(jié)束的操

24、作,也可以是與循環(huán)控制無關(guān)的需要循環(huán)執(zhí)行的任意表達(dá)式,甚至可以將循環(huán)體中的操作全部放到表達(dá)式3中。“表達(dá)式1”和“表達(dá)式3”可以是一個(gè)簡單的表達(dá)式,也可以是逗號表達(dá)式。 “表達(dá)式2”一般是關(guān)系表達(dá)式或邏輯表達(dá)式,但也可以是數(shù)值表達(dá)式或字符表達(dá)式,只要其值為非零,就執(zhí)行循環(huán)體。 可以用break語句跳出本層while循環(huán),用continue語句結(jié)束本層、本次while循環(huán)。 for語句的流程圖表示如下圖所示。 for語句的執(zhí)行過程是:1. 求解“表達(dá)式1”。2. 求解“表達(dá)式2”,若其值為真,則執(zhí)行循環(huán)體語句,然后轉(zhuǎn)到第3步。若其值為假,則轉(zhuǎn)到第5步。3. 求解“表達(dá)式3”。4. 返回上面第2步

25、繼續(xù)執(zhí)行。5. 循環(huán)結(jié)束。 for語句的功能是:既可以實(shí)現(xiàn)循環(huán)次數(shù)可以確定的循環(huán),也可以實(shí)現(xiàn)循環(huán)次數(shù)不能確定的循環(huán)。 循環(huán)結(jié)構(gòu)的嵌套 一個(gè)循環(huán)體內(nèi)又包含另一個(gè)完整的循環(huán)結(jié)構(gòu),稱為循環(huán)的嵌套。內(nèi)嵌的循環(huán)中還可以嵌套循環(huán),這就是多層循環(huán)。三種循環(huán)(while循環(huán)、do-while循環(huán)和for循環(huán))可以互相嵌套。 三種循環(huán)語句的比較 程序舉例【例1】求1+2+100,并輸出結(jié)果。分析:我們可以通過多個(gè)操作步驟解決這個(gè)問題:首先計(jì)算前兩個(gè)加數(shù)的和;其次使用求得的和與第三個(gè)加數(shù)相加,計(jì)算出前三個(gè)加數(shù)的和;再其次使用求得的和與第四個(gè)加數(shù)相加,計(jì)算出前四個(gè)加數(shù)的和;如此繼續(xù)下去,直到計(jì)算出前100個(gè)加數(shù)的和

26、。第1次:計(jì)算1+2;第2次:計(jì)算(1+2)+3;第3次:計(jì)算(1+2+3)+4;第99次:計(jì)算(1+.+99)+100。從上面的分析可以看出:這個(gè)問題可以通過99次加法運(yùn)算完成,并且每次作加運(yùn)算的操作對象加數(shù)與被加數(shù)的變化都是各有規(guī)律的: 容易看出加數(shù)從2變化到100,第一個(gè)加數(shù)是2,加數(shù)每次增加1即后一個(gè)加數(shù)比前一個(gè)加數(shù)增加1,最后一個(gè)加數(shù)是100; 第一個(gè)被加數(shù)是1,以后每次都使用上一次的和,最后一個(gè)被加數(shù)是1+.+99。因此,可以使用循環(huán)結(jié)構(gòu)解決這個(gè)問題。能用循環(huán)結(jié)構(gòu)實(shí)現(xiàn)的問題一般具有以下特點(diǎn): 操作的執(zhí)行具有重復(fù)性; 操作對象的變化具有規(guī)律性。使用循環(huán)結(jié)構(gòu)解題。如何用循環(huán)結(jié)構(gòu)解題?這

27、里重點(diǎn)強(qiáng)調(diào)以下幾點(diǎn): 設(shè)置循環(huán)控制變量的初值。 找出循環(huán)體,即需要對哪些操作進(jìn)行循環(huán)。主要有以下3個(gè)方面:需要重復(fù)執(zhí)行的操作;重新設(shè)置操作對象的值,使其有規(guī)律地變化,以供下次循環(huán)使用;重新設(shè)置循環(huán)控制變量的值,使其有規(guī)律地變化,最終打破循環(huán)的條件,使程序能夠退出循環(huán)。 找出循環(huán)的條件。可以設(shè)置兩個(gè)整型變量add1、add2,分別用于存儲被加數(shù)、加數(shù)。令add1、add2的初值分別為1、2,每循環(huán)一次都需要進(jìn)行加運(yùn)算add1+add2,然后將和保存到add1中并使add2的值增1以供下次循環(huán)使用。循環(huán)條件的設(shè)置比較簡單,只需設(shè)置一個(gè)整型變量counter,表示循環(huán)次數(shù)。令counter的初值為1

28、,每循環(huán)一次使counter的值增1(對于while和do-while語句,需要把對循環(huán)控制變量的設(shè)置放在循環(huán)體中。對于for語句,即可以把對循環(huán)控制變量的設(shè)置放在表達(dá)式3中,也可以放在循環(huán)體中。),當(dāng)counter的值超過99時(shí)就結(jié)束循環(huán),即循環(huán)條件是counter=99。根據(jù)以上分析,容易畫出解決這個(gè)問題的流程圖。根據(jù)流程圖,容易編寫出程序(這里采用while語句)。main() int add1=1,add2=2,counter=1,sum; while(counter=99) add1= add1+add2; add2=add2+1; counter=counter+1; sum=ad

29、d1; printf(sum=%d,sum);程序的進(jìn)一步簡化:main() int add1=1,add2=2; while(add2=100) add1= add1+add2; add2=add2+1; printf(sum=%d, add1);練習(xí):采用do-while語句和for語句改寫該程序【例2】由用戶輸入一個(gè)字符串,求該字符串中的所有字符的ASCII碼值之和,并將結(jié)果輸出到屏幕。參考程序1:#includemain() int sum=0; char c; while(1) c=getchar(); if(c!=n) sum=sum+c; else break; printf(%

30、dn,sum);參考程序2:#includemain() int sum=0; char c; while(c=getchar()!=n) sum=sum+c; printf(%dn,sum);參考程序3:#includemain() int sum=0; char c; for(sum=0;(c=getchar()!=n;sum=sum+c) ;此for語句的循環(huán)體為空語句,把本來要在循環(huán)體內(nèi)進(jìn)行的操作放在了表達(dá)式3中,作用是一樣的。可見for語句書寫自由,可以在表達(dá)式中完成本來應(yīng)在循環(huán)體內(nèi)完成的操作。 printf(%dn,sum);【例3】譯密碼。為使電文保密,發(fā)報(bào)人往往按一定規(guī)律將其轉(zhuǎn)

31、換成密碼,收報(bào)人再按約定的規(guī)律將其譯回原文。例如,可以按以下規(guī)律將電文變成密碼:將字母A變成字母E、a變成e、W變成A、X變成B、Y變成C、Z變成D,即變成其后的第4個(gè)字母,如下圖所示。字母按上述規(guī)律轉(zhuǎn)換,非字母字符不變。例如:“China!”會被轉(zhuǎn)換為“Glmre!”。輸入一行字符,要求輸出其相應(yīng)的密碼。分析:對用戶輸入的字符串中的字符進(jìn)行逐個(gè)掃描和相應(yīng)的處理:先讀入第一個(gè)字符,判定它是否為大寫字母或小寫字母,若是,則將其值加4。這時(shí),對于由用戶輸入的AV和av已變成其后的第4個(gè)字母;而對于由用戶輸入的WZ和wz卻沒有達(dá)到同樣的效果,對這種情況還需作進(jìn)一步處理,辦法是使c減去26,這時(shí)對于由

32、用戶輸入的WZ和wz就變成其后的第4個(gè)字母了。第一個(gè)字符處理完后,再讀入第二個(gè)字符,進(jìn)行相應(yīng)的處理,如此反復(fù),直到處理完用戶輸入的字符串中的最后一個(gè)字符為止。從上面的分析可以看出:我們需要使用循環(huán)來實(shí)現(xiàn)對用戶輸入的字符串中的字符進(jìn)行逐個(gè)掃描和所進(jìn)行的相應(yīng)的處理,該循環(huán)結(jié)束的條件是getchar()!=n。 程序如下:#includemain() char c; while(c=getchar()!=n) if(c=a&c=A&cZ&cz)如果加4以后有cZ&cz,則表示原來的字母在wz中。還有一點(diǎn)需要注意: 條件cZ&cZ,因?yàn)楫?dāng)用戶輸入的是小寫字母時(shí)也滿足cZ,從而也執(zhí)行c=c-26;,這就

33、會出錯。因此必須限制其范圍為cZ&cz沒有必要寫成cz & cz成立時(shí),必有條件cz+4。 ) c=c-26; printf(%c,c); 【例4】由用戶輸入一個(gè)大于或等于3的整數(shù),判斷該數(shù)是否為素?cái)?shù),并將判斷結(jié)果輸出到屏幕。分析:素?cái)?shù)是指除了1和該數(shù)本身之外,不能被其他任何整數(shù)整除的數(shù)。判斷一個(gè)大于或等于3的整數(shù)n為素?cái)?shù)的方法為:將n作為被除數(shù),將2到各個(gè)整數(shù)輪流作為除數(shù),如果都不能被整除,則n為素?cái)?shù)。流程圖1:讓n被2到除,如果n能被2到之中任何一個(gè)整數(shù)整除,即某一次r= =0,則打印n為非素?cái)?shù),并提前結(jié)束循環(huán)(此時(shí)必然有i,意味著沒有一個(gè)i(2)能整除n。由上圖可以看出,圖中間那個(gè)循環(huán)部

34、分有兩個(gè)出口(一個(gè)在第二個(gè)菱形框下面出口,另一個(gè)在第一個(gè)菱形框右邊出口),不符合基本結(jié)構(gòu)的特點(diǎn),所以這個(gè)流程圖不是由三種基本結(jié)構(gòu)組成的,在編寫程序時(shí),就不可避免要使用goto語句,這不是我們所希望的。我們可以對上圖做必要的變換將第一個(gè)菱形框(“r= =0”)的兩個(gè)出口匯合在一點(diǎn),以解決兩個(gè)出口問題。具體的作法是:將輸出框打印n“不是素?cái)?shù)”的出口線改為指向第二個(gè)菱形框。但這樣一來,會產(chǎn)生如下兩個(gè)問題: 當(dāng)r= =0時(shí),程序執(zhí)行了輸出框打印n“不是素?cái)?shù)”后就不應(yīng)繼續(xù)循環(huán),而要求退出循環(huán)。所以還需要在第二個(gè)菱形框中增加一個(gè)循環(huán)終止條件:r= =0,說明找到了一個(gè)i(2)能整除n,并執(zhí)行了輸出框打印n

35、“不是素?cái)?shù)”,即將第二個(gè)菱形框中的循環(huán)終止條件改為i|r= =0,表示如果出現(xiàn)i或r= =0情況之一,就會退出此循環(huán)。 當(dāng)r= =0時(shí),程序執(zhí)行了輸出框打印n“不是素?cái)?shù)”并退出循環(huán)后就不應(yīng)繼續(xù)執(zhí)行輸出框打印n“是素?cái)?shù)”,而要求跳過此操作。所以還需要在輸出框打印n“是素?cái)?shù)”之前增加一個(gè)執(zhí)行條件:i(或用r!=0),說明未找到一個(gè)i(2)能整除n,并未執(zhí)行輸出框打印n“不是素?cái)?shù)”而提前結(jié)束循環(huán),表示如果i(或用r!=0),就會執(zhí)行此操作。修改后的流程圖就是結(jié)構(gòu)化的了,如下圖所示:相應(yīng)的程序如下:#includemain() int n,i,r,k; printf(Input an int numb

36、er(the number=3):); scanf(%d,&n); k=sqrt(n+1);加1是為了避免在求時(shí)可能出現(xiàn)的誤差。 i=2; do r=n%i; if(r= =0) printf(%d is not a Prime number.n,n); else i=i+1; while(!(ik|r= =0); if(ik) printf(%d is a Prime muber.n,n);當(dāng)r= =0時(shí),也可以不直接打印n“不是素?cái)?shù)”,修改后的流程圖如下圖所示:還可以增加一個(gè)標(biāo)志量w,w的初值為0。也可以不預(yù)先在此處設(shè)置w的初值為0,如果這樣,就需要在循環(huán)中每次r!=0時(shí),都執(zhí)行w=0賦值

37、操作。兩種方案相比較,還是第一種優(yōu)化。執(zhí)行循環(huán)時(shí),如果r= =0(r= =0意味著找到了一個(gè)i(2)能整除n,從而可知n為非素?cái)?shù))則使w的值變成1,并退出循環(huán);如果r!=0(r!=0意味著當(dāng)前的i(2)不能整除n)則保持w的值為0,并在ik|r= =0)也可以改寫成:!(ik|w= =1)。 第三個(gè)菱形框中的條件i(或用r!=0)也可以改寫成:w= =0。修改后的流程圖如下圖所示:流程圖2:使用break語句(可以發(fā)現(xiàn)使用break語句的程序也不是結(jié)構(gòu)化的。)?!纠?】輸出100200間的全部素?cái)?shù)。在例2的基礎(chǔ)上,對本題用一個(gè)嵌套循環(huán)即可處理。程序如下:#includemain() int n

38、,i,r,k; for(n=100;n=200;n+) k=sqrt(n+1); i=2; do r=n%i; if(r=0) break; i=i+1; while(ik) printf(%dn,n); 4 轉(zhuǎn)向 “轉(zhuǎn)向”是語言表達(dá)所需要的。C語言提供的描述“轉(zhuǎn)向”的語句有:goto語句、break語句、continue語句、return語句。 break語句break;說明:break語句只能用于循環(huán)語句和switch語句中。當(dāng)break語句用于循環(huán)語句中時(shí),一般作為循環(huán)語句中內(nèi)嵌的選擇語句的一個(gè)分支。如果有以下循環(huán)結(jié)構(gòu):while(表達(dá)式1)if(表達(dá)式2) break;則其流程圖表示如

39、下圖所示。break語句的功能是:break語句用于switch語句中時(shí),用于跳出本層switch語句。break語句用于循環(huán)語句中時(shí),用于跳出本層循環(huán),提前結(jié)束本層循環(huán),即不再繼續(xù)執(zhí)行本層其余的幾次循環(huán)。 continue語句continue;說明:continue語句只能用于循環(huán)語句中。當(dāng)continue語句用于循環(huán)語句中時(shí),一般作為循環(huán)語句中內(nèi)嵌的選擇語句的一個(gè)分支。如果有以下循環(huán)結(jié)構(gòu):while(表達(dá)式1)if(表達(dá)式2) continue;則其流程圖表示如下圖所示。continue語句的功能是:continue語句用于結(jié)束本層、本次循環(huán),即跳過循環(huán)體中下面尚未執(zhí)行的語句,接著進(jìn)行下一

40、次是否執(zhí)行循環(huán)的判定。用于跳出本層循環(huán)語句,提前結(jié)束本層循環(huán),即不再繼續(xù)執(zhí)行本層其余的幾次循環(huán)。 return語句return;或return 表達(dá)式;說明: 在一個(gè)函數(shù)體中可以包含多個(gè)return語句,它們一般位于不同的執(zhí)行路徑上,否則總有一些return語句在任何情況下都執(zhí)行不到。 當(dāng)一個(gè)函數(shù)的結(jié)果類型被說明為void類型時(shí),在該函數(shù)體中只能使用不帶表達(dá)式的return語句,這種函數(shù)體中也可以不使用return語句。這是因?yàn)檫@種函數(shù)一般充作Pascal、Ada等語言意義下的過程使用,只用于完成某種特定動作,而不是用于求得某個(gè)值,因而在return語句中不需要帶表達(dá)式,return語句的作用

41、僅用于從被調(diào)用函數(shù)返回給調(diào)用函數(shù)。這種函數(shù)體中也可以不使用return語句。在這種情況下,當(dāng)函數(shù)執(zhí)行到其體中邏輯上的最后一個(gè)語句(即執(zhí)行到函數(shù)體最后的右花括號“”)時(shí)便會終止該函數(shù)的執(zhí)行并將控制返回給調(diào)用者,即相當(dāng)于在這個(gè)“”前有一個(gè)缺省的return語句。 當(dāng)一個(gè)函數(shù)的結(jié)果類型被說明為除void類型之外的其它類型(包括指向void的指針類型)時(shí),在該函數(shù)體中就只能(也必須)使用帶表達(dá)式的return語句。這是因?yàn)檫@種函數(shù)一般用于求某個(gè)值(當(dāng)然也不排除它同時(shí)要完成某些其它的動作),這個(gè)值是在函數(shù)執(zhí)行結(jié)束時(shí)作為函數(shù)執(zhí)行的結(jié)果返回給該函數(shù)的調(diào)用者。在C語言中,這個(gè)結(jié)果值必須也只能用return語句

42、返回。因此,帶表達(dá)式的return語句有兩個(gè)作用:一是傳送函數(shù)的計(jì)算結(jié)果,二是終止當(dāng)前函數(shù)的執(zhí)行將控制返回給調(diào)用者。 當(dāng)一個(gè)需要在執(zhí)行結(jié)束時(shí)返回值的函數(shù)在執(zhí)行過程中遇到不帶表達(dá)式的return語句時(shí),由于它不能返回一個(gè)確定的值,因而該函數(shù)的執(zhí)行結(jié)果是不確定的。如果這種函數(shù)在執(zhí)行到最末的“”時(shí)仍沒有遇到return語句,那么也相當(dāng)于執(zhí)行了一個(gè)不帶表達(dá)式的return語句,因而其行為也是不確定的。因此,在定義這種函數(shù)時(shí),要保證所有執(zhí)行路徑執(zhí)行結(jié)束前(即在所有執(zhí)行路徑中)都要包含一個(gè)帶表達(dá)式的return語句。當(dāng)然,當(dāng)多個(gè)執(zhí)行路徑合為一處時(shí),也可共用一個(gè)return語句。 如果某一return語句中

43、表達(dá)式的類型與函數(shù)所要返回的類型不同,那么就要把該表達(dá)式的類型轉(zhuǎn)換成函數(shù)的結(jié)果類型后再返回給調(diào)用者。而且,如果在一個(gè)函數(shù)的定義之前先對之進(jìn)行了調(diào)用,并且在調(diào)用前對該函數(shù)所作的說明(包括隱式說明)與return語句所返回值的類型不同(即使return語句所返回值的類型與函數(shù)定義時(shí)所說明的結(jié)果類型相同),那么也要把return語句所返回值的類型轉(zhuǎn)換成該函數(shù)說明所說明的結(jié)果類型。 return語句的執(zhí)行過程是:當(dāng)一個(gè)被調(diào)用函數(shù)執(zhí)行過程中遇到return語句時(shí),該函數(shù)的當(dāng)前執(zhí)行便告終止,程序接著從調(diào)用該函數(shù)的那個(gè)函數(shù)(例如:可能是main函數(shù))的下一個(gè)動作點(diǎn)(也可能是下一個(gè)語句)接著往下執(zhí)行(注意:對

44、于帶表達(dá)式的return語句還需要考慮: 是否需要對return語句中的表達(dá)式的結(jié)果進(jìn)行類型轉(zhuǎn)換。 返回函數(shù)的計(jì)算結(jié)果)。return語句的功能是:不帶表達(dá)式的return語句的作用是終止當(dāng)前函數(shù)的執(zhí)行,并把控制從被調(diào)用函數(shù)返回給該函數(shù)的調(diào)用者繼續(xù)執(zhí)行。 帶表達(dá)式的return語句有兩個(gè)作用:一是傳送函數(shù)的計(jì)算結(jié)果,二是終止當(dāng)前函數(shù)的執(zhí)行將控制返回給調(diào)用者。5 結(jié)構(gòu)化的程序傳統(tǒng)程序的弊端程序員可以不受限制地使流程隨意地轉(zhuǎn)來轉(zhuǎn)去(使用goto等跳轉(zhuǎn)語句,特別是goto語句能使流程隨意地轉(zhuǎn)來轉(zhuǎn)去。),這種情況如下圖所示。這種如同亂麻一樣的算法稱為BS型算法,意為一碗面條(a bowl of spa

45、ghetti),亂無頭緒。這種算法難以閱讀,也難以修改,從而使算法的可靠性和可維護(hù)性難以保證。為了提高算法的質(zhì)量,使算法的設(shè)計(jì)閱讀方便,必須限制箭頭的濫用,即不允許無規(guī)律地使流程隨意轉(zhuǎn)向,只能順序地進(jìn)行下去。但算法上難免包含一些分支和循環(huán),還可能包含一些流程的向前或向后的非順序轉(zhuǎn)向,而不可能全部由一個(gè)一個(gè)操作順序組成。為了解決這個(gè)問題,人們設(shè)想,規(guī)定出幾種基本結(jié)構(gòu),然后由這些基本結(jié)構(gòu)按一定規(guī)律組成一個(gè)算法結(jié)構(gòu)(如同一些基本預(yù)制構(gòu)件來搭成房屋一樣),算法的質(zhì)量就能得到保證和提高。三種基本結(jié)構(gòu)和結(jié)構(gòu)化的程序1966年,Bohra和Jacopini提出了以下三種基本結(jié)構(gòu),作為表示一個(gè)良好算法的基本單元。(1) 順序結(jié)構(gòu)(2) 選擇結(jié)構(gòu)(3) 循環(huán)結(jié)構(gòu)以上三種基本

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論