第程序的流程設(shè)計(jì)PPT課件_第1頁
第程序的流程設(shè)計(jì)PPT課件_第2頁
第程序的流程設(shè)計(jì)PPT課件_第3頁
第程序的流程設(shè)計(jì)PPT課件_第4頁
第程序的流程設(shè)計(jì)PPT課件_第5頁
已閱讀5頁,還剩145頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、他認(rèn)為,“程序就是在數(shù)據(jù)的某些特定表示方式和結(jié)構(gòu)的基礎(chǔ)上對(duì)抽象算法的具體表述”。Wirth企圖用這個(gè)公式來對(duì)程序進(jìn)行一個(gè)概括性的定義。從今天的觀點(diǎn)來看,它只能是對(duì)過程化程序的一個(gè)抽象定義,對(duì)面向?qū)ο蟮某绦蚨詣t不盡然。不過對(duì)學(xué)習(xí)C語言這樣的面向過程的程序設(shè)計(jì)語言而言,是完全適用的。也就是說,面向過程的程序有兩大要素:算法和數(shù)據(jù)結(jié)構(gòu)。數(shù)據(jù)結(jié)構(gòu)是程序所處理的對(duì)象數(shù)據(jù)的表示和組織形式。數(shù)據(jù)類型就是其重要內(nèi)容。關(guān)于數(shù)據(jù)結(jié)構(gòu)的概念在學(xué)習(xí)完第5、6、7章后,才會(huì)有較深的體驗(yàn)。第1頁/共150頁算法的組成要素與基本性質(zhì) 算法含有兩大要素: (1)操作算法是由一系列操作組成的。每個(gè)操作的確定不僅取決于問題的需

2、求,還取決于它們?nèi)∽阅膫€(gè)操作集,它與使用的工具系統(tǒng)有關(guān)。如算盤上的操作集由進(jìn)、退、上、下、去等組成;做菜的操作集包括坐鍋、加油、炒、煮、炸、蒸、燜、加水、加調(diào)料等;駕駛汽車的操作包括踩離合器、踩油門、開電門、換檔、左轉(zhuǎn)、右轉(zhuǎn)、開燈、關(guān)燈等。計(jì)算機(jī)算法要由計(jì)算機(jī)實(shí)現(xiàn),組成它的操作集是計(jì)算機(jī)所能進(jìn)行的操作。而且這些操作的描述與程序設(shè)計(jì)語言的級(jí)別有關(guān)。在高級(jí)語言中所描述的操作主要包括:算術(shù)運(yùn)算(+、-、*、/)、邏輯運(yùn)算(“與”、“或”、“非”等)、關(guān)系運(yùn)算(=、=、=、!=等)、函數(shù)運(yùn)算、位運(yùn)算、I/O操作等。計(jì)算機(jī)算法是由這些操作所組成的。第2頁/共150頁 (2)控制結(jié)構(gòu)算法的另一要素是其控制

3、結(jié)構(gòu)。每一個(gè)算法都要由一系列的操作組成。同一操作序列,按不同的順序執(zhí)行,就會(huì)得出不同的結(jié)果??刂平Y(jié)構(gòu)即如何控制組成算法的各操作的執(zhí)行順序。結(jié)構(gòu)化程序設(shè)計(jì)方法要求:一個(gè)程序只能由三種基本控制結(jié)構(gòu)(或由它們派生出來的結(jié)構(gòu))組成。1966年Bohm和Jacopini證明,由這三種基本結(jié)構(gòu)可以組成任何結(jié)構(gòu)的算法,解決任何問題。這三種基本結(jié)構(gòu)是:第3頁/共150頁(1) 順序結(jié)構(gòu)。順序結(jié)構(gòu)中的語句是按書寫的順序執(zhí)行的,即語句的執(zhí)行順序與書寫順序一致。這種結(jié)構(gòu)像一串珍珠項(xiàng)鏈一樣清晰可讀。這是一種理想的結(jié)構(gòu),但是光有這樣的結(jié)構(gòu)不可能處理復(fù)雜的問題。 一般說來,程序中的語句是順序執(zhí)行的。但是,順序執(zhí)行的程序的

4、功能是非常有限的。為了提高程序的靈活性,必須采用不同的程序流程結(jié)構(gòu)。 (2) 選擇結(jié)構(gòu)。最基本的選擇結(jié)構(gòu)是當(dāng)程序執(zhí)行到某一語句時(shí),要進(jìn)行一下判斷,從兩種路徑中選擇一條。例如,要在兩個(gè)數(shù)a,b中取一個(gè)最大的數(shù)就要經(jīng)過比較判斷,決定是將a還是將b輸出。選擇結(jié)構(gòu)給程序注入最簡單的智能。 由二分支選擇,可以派生出多分支選擇結(jié)構(gòu)。(3) 循環(huán)結(jié)構(gòu)(或稱重復(fù)結(jié)構(gòu))。這種結(jié)構(gòu)是將一條或多條語句重復(fù)地執(zhí)行若干遍。就像驢子拉磨一樣,雖然每一圈的操作都比較簡單,而且相同,但磨上若干圈后就能把麥子磨成面粉。眾所周知,電子計(jì)算機(jī)的一大優(yōu)勢(shì)是速度快。當(dāng)能把一個(gè)復(fù)雜問題用循環(huán)結(jié)構(gòu)來實(shí)現(xiàn)時(shí),就能充分地發(fā)揮計(jì)算機(jī)的高速度的優(yōu)

5、勢(shì)。第4頁/共150頁2. 算法的基本性質(zhì) 簡單地說,算法就是進(jìn)行操作的方法和操作步驟。例如,菜譜實(shí)際上是做菜肴的算法,樂譜實(shí)際上是演奏的算法,計(jì)算機(jī)程序是用某種程序設(shè)計(jì)語言描述的解題算法。通常認(rèn)為算法有如下一些性質(zhì):(1)有效性 有效性指算法所規(guī)定的操作都應(yīng)當(dāng)是能夠有效執(zhí)行的。例如,對(duì)于操作汽車的算法,有效的操作就是加速、剎車、換檔、轉(zhuǎn)動(dòng)方向盤、鳴笛等,要讓汽車執(zhí)行“跳起”就是無效的操作。同樣,一個(gè)計(jì)算機(jī)算法必須是計(jì)算機(jī)能夠執(zhí)行的。(2)確定性 確定性具有兩重意義:一是所描述的操作應(yīng)當(dāng)具有明確的意義,不應(yīng)當(dāng)有歧義性。例如,不能發(fā)出這樣的操作指令:“執(zhí)行一個(gè)算術(shù)操作”。因?yàn)樗葲]有指出算術(shù)操作

6、的類型,也沒有指出操作數(shù)。確定性的另一重意義: 操作作序列只有一個(gè)初始動(dòng)作,序列中每一動(dòng)作僅有一個(gè)后繼動(dòng)作; 序列終止表示問題得到解答或問題沒有解答,不能沒有任何結(jié)論。(3)有窮性 有窮性指算法所規(guī)定的操作序列必須在允許的時(shí)間內(nèi)結(jié)束。例如,一個(gè)計(jì)算機(jī)算法要執(zhí)行100年以上,就失去有窮性。第5頁/共150頁算法描述工具 為了描述算法,人們創(chuàng)建了許多算法描述工具。下面介紹程序設(shè)計(jì)中常用的幾種方法,并主要介紹如何用這些工具描述算法的三種基本結(jié)構(gòu)。1. 流程圖 流程圖是一種流傳很廣的算法描述工具。這種工具的特點(diǎn)是用一些圖框表示各種類型的操作,用線表示這些操作的執(zhí)行順序。我國國家標(biāo)準(zhǔn)GB 152689中

7、推薦的一套流程圖標(biāo)準(zhǔn)化符號(hào),它與國際標(biāo)準(zhǔn)化組織ISO(International Standard Organization)提出的ISO流程圖符號(hào)是一致的。圖3.2為其中常用的一些符號(hào)。第6頁/共150頁過程判斷數(shù)據(jù)預(yù)定義過程起止流程線連接注釋圖圖3.2 常用的流程圖標(biāo)準(zhǔn)化符號(hào)常用的流程圖標(biāo)準(zhǔn)化符號(hào) 第7頁/共150頁2. 算法的基本性質(zhì) 簡單地說,算法就是進(jìn)行操作的方法和操作步驟。例如,菜譜實(shí)際上是做菜肴的算法,樂譜實(shí)際上是演奏的算法,計(jì)算機(jī)程序是用某種程序設(shè)計(jì)語言描述的解題算法。通常認(rèn)為算法有如下一些性質(zhì):(1)有效性 有效性指算法所規(guī)定的操作都應(yīng)當(dāng)是能夠有效執(zhí)行的。例如,對(duì)于操作汽車的

8、算法,有效的操作就是加速、剎車、換檔、轉(zhuǎn)動(dòng)方向盤、鳴笛等,要讓汽車執(zhí)行“跳起”就是無效的操作。同樣,一個(gè)計(jì)算機(jī)算法必須是計(jì)算機(jī)能夠執(zhí)行的。(2)確定性 確定性具有兩重意義:一是所描述的操作應(yīng)當(dāng)具有明確的意義,不應(yīng)當(dāng)有歧義性。例如,不能發(fā)出這樣的操作指令:“執(zhí)行一個(gè)算術(shù)操作”。因?yàn)樗葲]有指出算術(shù)操作的類型,也沒有指出操作數(shù)。確定性的另一重意義: 操作作序列只有一個(gè)初始動(dòng)作,序列中每一動(dòng)作僅有一個(gè)后繼動(dòng)作; 序列終止表示問題得到解答或問題沒有解答,不能沒有任何結(jié)論。(3)有窮性 有窮性指算法所規(guī)定的操作序列必須在允許的時(shí)間內(nèi)結(jié)束。例如,一個(gè)計(jì)算機(jī)算法要執(zhí)行100年以上,就失去有窮性。第8頁/共1

9、50頁 下面對(duì)其中一些主要符號(hào)作簡要說明。平行四邊形表示數(shù)據(jù),其中可注明數(shù)據(jù)名稱、來源、用途或其它的文字說明。處理矩形表示各種處理功能。例如,執(zhí)行一個(gè)或一組特定的操作,從而使信息的值、信息形式或所在位置發(fā)生變化。矩形內(nèi)可注明處理名稱或其簡要功能。預(yù)定義過程帶有雙豎邊線的矩形,表示已命名的處理。該處理為在另外地方已得到詳細(xì)說明的一個(gè)操作或一組操作。例如庫函數(shù)或其它已定義的函數(shù)等。矩形內(nèi)可注明特定處理名稱或其簡要功能。判斷菱形表示判斷。菱形內(nèi)可注明判斷的條件。它只有一個(gè)入口,但可以有若干個(gè)可供選擇的出口,在對(duì)定義的判斷條件求值后,有一個(gè)且僅有一個(gè)出口被選擇。求值結(jié)果可在表示出口路徑的流線附近寫出。

10、流線直線表示執(zhí)行的流程。當(dāng)流程自上向下或由左向右時(shí),流程線可不帶箭頭,其它情況應(yīng)加箭頭表示流程。端點(diǎn)。扁圓形表示轉(zhuǎn)向外部環(huán)境或從外部環(huán)境轉(zhuǎn)入的端點(diǎn)符。例如,程序流程的起、始點(diǎn)。注解。注解是程序的編寫者向閱讀者提供的說明。注解符由縱邊線構(gòu)成,它用虛線連接到被注解的符號(hào)或符號(hào)組上。 第9頁/共150頁 圖3.3(a)、(b)、(c)中的虛線框,分別為用流程圖表示的三種基本流程控制結(jié)構(gòu)。這三種基本結(jié)構(gòu)有一個(gè)明顯的特征:單入口和單出口。從整體上看都相當(dāng)于一個(gè)處理框。用它們所組成的程序來龍去脈十分清晰。S1S2S3PS1S2真假PS2假真(a)順序結(jié)構(gòu))順序結(jié)構(gòu) (b)選擇結(jié)構(gòu))選擇結(jié)構(gòu) (c)重復(fù)結(jié)構(gòu)

11、)重復(fù)結(jié)構(gòu) 圖圖3.3 用流程圖描述的三種流程基本結(jié)構(gòu)用流程圖描述的三種流程基本結(jié)構(gòu) 第10頁/共150頁例3.1 用流程圖描述從三個(gè)數(shù)中取最大數(shù)的算法。從三個(gè)數(shù)中取最大數(shù)的算法思路是:假定這三個(gè)數(shù)是a,b,c,則首先可以比較a,b兩數(shù),從中選大者;然后再用這個(gè)大數(shù)與數(shù)c比較,從中取大者。這時(shí)得到的大數(shù),就是三個(gè)數(shù)中的最大數(shù)。這個(gè)算法用流程圖描述如圖3.4(a)所示。通常,求解一個(gè)問題的算法不是唯一的。例如圖3.4(b)也是一個(gè)三數(shù)中取大的算法。它的基本思路是,先設(shè)max=0,然后依次輸入i個(gè)數(shù),每輸入一個(gè)數(shù),與max比較一次,把大的放入max中。當(dāng)輸完i個(gè)數(shù)時(shí),max中存放的就是這i個(gè)數(shù)中的

12、最大數(shù)。這里,i是一個(gè)計(jì)數(shù)器,用于統(tǒng)計(jì)輸入數(shù)的個(gè)數(shù),所以每輸入一個(gè)數(shù),要執(zhí)行一次自增操作。這個(gè)算法與圖3.4(a)所示算法的不同在于: 算法結(jié)構(gòu)不同:圖3.4(a)所示算法采用了兩個(gè)選擇結(jié)構(gòu),而圖3.4(b)所示算法采用了一個(gè)循環(huán)結(jié)構(gòu)和一個(gè)選擇結(jié)構(gòu)。 算法的靈活性不同:圖3.4(b)中的算法可以用來求任意個(gè)數(shù)中的最大數(shù)。第11頁/共150頁a=b輸入a,b,cmax=a真假max=bmax=c真假輸出max輸出c開始結(jié)束i=maxmax=n(a)一個(gè)三數(shù)中取大的算法)一個(gè)三數(shù)中取大的算法 (b)另一個(gè)三數(shù)中取大的算法)另一個(gè)三數(shù)中取大的算法 圖圖3.4 三數(shù)中取大算法的流程圖描述三數(shù)中取大算法

13、的流程圖描述 第12頁/共150頁用流程圖表示算法靈活、自由、形象、直觀,可以表示任何算法。它允許用流線使流程任意轉(zhuǎn)移。但這卻是程序設(shè)計(jì)中的一個(gè)隱患,程序中如果允許流程毫無限制地任意轉(zhuǎn)移,就會(huì)使程序如同一團(tuán)亂麻一樣難以閱讀和維護(hù),如圖3.5所示。這種程序叫做BS程序(a Bowl of Spaghetti的縮寫,意為“一碗面條”似的)。圖圖3.5 無限制地使用流線形成無限制地使用流線形成BS流程結(jié)構(gòu)流程結(jié)構(gòu) 結(jié)構(gòu)化程序設(shè)計(jì)主張限制這種無規(guī)律的任意轉(zhuǎn)向,采用三種基本結(jié)構(gòu)作為構(gòu)成程序的基本單位。這樣就必須限制流線的使用。第13頁/共150頁 2. N-S圖描述靈活的流線是程序中隱藏錯(cuò)誤的禍根。針對(duì)

14、這一弊病,1973年美國學(xué)者I. Nassi和B. Shneiderman提出了一種無流線的流程圖,稱為N-S圖。它的三種基本結(jié)構(gòu)如圖3.6所示。N-S圖的每一種基本結(jié)構(gòu)都是一個(gè)矩形框,整個(gè)算法可以像堆積木一樣堆成。其中,(a)為三個(gè)操作組成的順序結(jié)構(gòu);(b)為二分支的選擇結(jié)構(gòu);(c)為當(dāng)型重復(fù)結(jié)構(gòu),即當(dāng)命題P 為“真”時(shí),就重復(fù)執(zhí)行S。由于N-S圖中沒有了流線,所以絕對(duì)不會(huì)出現(xiàn)由于亂用流線造成的BS算法結(jié)構(gòu)。第14頁/共150頁S1S2S3PS1S2當(dāng)PS假真(c)當(dāng)型重復(fù)結(jié)構(gòu))當(dāng)型重復(fù)結(jié)構(gòu)(a)順序結(jié)構(gòu))順序結(jié)構(gòu) (b)選擇結(jié)構(gòu))選擇結(jié)構(gòu)圖圖3.6 用用N-S圖描述三種基本流程結(jié)構(gòu)圖描述三

15、種基本流程結(jié)構(gòu) 第15頁/共150頁 圖3.7(a)、(b)給出了用與圖3.4(a)、(b)流程圖對(duì)應(yīng)的N-S圖。注意,空白的處理框表示沒有操作。a=bmax=amax=b輸入a,b,c假真max=c輸出max輸出c真假當(dāng)i=maxmax=n真假輸入n初始化:max=0,i=1輸出max(a)采用選擇結(jié)構(gòu))采用選擇結(jié)構(gòu) (b)采用當(dāng)型重復(fù)結(jié)構(gòu))采用當(dāng)型重復(fù)結(jié)構(gòu) 圖圖3.7 三數(shù)中取大算法的三數(shù)中取大算法的N-S圖描述圖描述 第16頁/共150頁 3. 偽代碼偽代碼(pseudo code)是用介于自然語言與計(jì)算機(jī)語言之間的文字符號(hào)算法描述的工具。它無固定的、嚴(yán)格的語法規(guī)則,通常是借助某種高級(jí)語

16、言的控制結(jié)構(gòu),中間的操作可以用自然語言(如中文或英文),也可以用程序設(shè)計(jì)語言,或使用自然語言與程序設(shè)計(jì)語言的混合體。一般專業(yè)人員習(xí)慣用偽代碼進(jìn)行算法描述。下面是與圖3.7相對(duì)應(yīng)的三數(shù)中取大算法的偽代碼描述。 (1)與圖3.7(a)相對(duì)應(yīng)的三數(shù)中取大算法的偽代碼描述:輸入輸入a,b,c;if(a=b)max=a;else max=bif(max=c) 輸出輸出max;else 輸出輸出c;第17頁/共150頁(2)與圖3.7(b)相對(duì)應(yīng)的三數(shù)中取大算法的偽代碼描述:初始化:初始化:mac=0,i=1;當(dāng)(當(dāng)(i=max) max=n;)輸出輸出max;(3)與圖3.7(c)相對(duì)應(yīng)的三數(shù)中取大算法

17、的偽代碼描述:初始化:初始化:mac=0,i=1; (輸入輸入n; i+;if(n=max) max=n;) 直到(直到(i3)輸出輸出max;第18頁/共150頁自頂向下,逐步細(xì)化的算法設(shè)計(jì)過程算法設(shè)計(jì)是一個(gè)的智力過程。設(shè)計(jì)復(fù)雜問題的算法更是一個(gè)高強(qiáng)度的智力勞動(dòng)。實(shí)踐證明,保證算法設(shè)計(jì)正確的一個(gè)方法是要讓問題的復(fù)雜性能夠在人的智力容易控制范圍之內(nèi)。為此人們提出了一種自頂向下、逐步細(xì)化的算法設(shè)計(jì)方法。按照這種方法,解題之初不要一下子就力圖觸及到問題解法的細(xì)節(jié),而應(yīng)當(dāng)從問題的全局出發(fā),給出高度概括、抽象的算法,通常是把這些問題的求解分成可以獨(dú)立求解的若干子問題;接著對(duì)每一個(gè)子問題,再進(jìn)行分解;最

18、后對(duì)不可再分的子問題分別設(shè)計(jì)算法,而且設(shè)計(jì)的過程也是從概括逐步細(xì)化。一般說來,上層解決的是“做什么”的過程,逐步細(xì)化的過程是解決“怎么做”的過程。在用偽代碼描述算法時(shí),隨著逐步細(xì)化,最終可以用程序設(shè)計(jì)語言代替算法中的偽代碼。等到全部偽代碼都用某種程序設(shè)計(jì)語言描述了,程序設(shè)計(jì)也就基本完成了。第19頁/共150頁例3.2 用自頂向下、逐步細(xì)化的方法設(shè)計(jì)三數(shù)中取大算法的過程。 這里,僅考慮采用偽代碼描述的方法。 (1) 首先,把該問題分析為: s1: 輸入三數(shù)輸入三數(shù)a,b,c;s2: 從從a,b,c中找出大數(shù)賦給中找出大數(shù)賦給max;s3: 輸出輸出max。這一階段算法是用漢語描述的,描述了按順序

19、要完成的三個(gè)“做什么”??梢杂胹1,s2,s3代表第1步、第2步、第3步。s是步(step)的縮寫。 (2) 在前一階段的基礎(chǔ)上考慮各個(gè)“做什么”的實(shí)現(xiàn)途徑,把算法細(xì)化為:s1: 調(diào)用調(diào)用scanf()函數(shù);函數(shù);s2: 設(shè)計(jì)一個(gè)函數(shù)設(shè)計(jì)一個(gè)函數(shù)max3 (a,b,c);s3: 調(diào)用調(diào)用printf()函數(shù)。函數(shù)。這一階段是用混合語言寫算法。第20頁/共150頁(3) 寫主函數(shù)的條件已經(jīng)成熟。int main(void) /*三數(shù)中取大數(shù)三數(shù)中取大數(shù)*/float a,b,c, max;float max3(float x,float y, float z);printf (Input 3 n

20、umbers a b c:);scanf (%f%f%f, &a,&b,&c);max=max3(a,b,c);printf (The max is: %fn, max);return 0;第21頁/共150頁(4) 設(shè)計(jì)max 3()的算法。仍按逐步細(xì)化的方法,先給出概要算法。設(shè)三個(gè)參數(shù)為float x, float y, float z。s2.1: 從從x與與y中取大數(shù)送中取大數(shù)送m中;中;s2.2: 從從m與與z中取大數(shù)送中取大數(shù)送m中;中;s2.3: 返回返回m給主調(diào)函數(shù)。給主調(diào)函數(shù)。進(jìn)一步細(xì)化得 s2.1:if(xy)m=x;elsem=y;s2.2: if(

21、mz)m=m;elsem=z;s2.3: return (m); 第22頁/共150頁這就很容易用C語言立刻寫出函數(shù)max3()了:float max 3 (float x, float y, float z)float m;if (xy)m=x;elsem=y;if (mz)m=m;elsem=z;return (m);一次執(zhí)行結(jié)果:Input 3 numbers a b c: 34.7 45.9 678The max is: 678.000000第23頁/共150頁命題的“真”、“假”與C語言中的邏輯值不論是選擇結(jié)構(gòu),還是循環(huán)結(jié)構(gòu),流程的改變都是由判斷決定的。即需要根據(jù)判斷決定選擇,根據(jù)判

22、斷決定是否循環(huán)以及循環(huán)的結(jié)束。通常,判斷是針對(duì)命題的“真”、“假”進(jìn)行的。例如,下面是一些命題: (行駛中)前面的交通信號(hào)燈是紅色的。 今天下雨。 ab。 abc,即ab 且bc。 ab 或cb。 如果a不能被b整除。這些命題的值都只能是一個(gè)邏輯(布爾)值:“真”或“假”。早期的C語言不提供專門的邏輯(布爾)類型,規(guī)定用非0值表示“真”,用0值表示“假”。這樣,不管任何表達(dá)式,只要其值為非0(包括負(fù)數(shù)),就說明其為“真”;只要其值為0,就說明其為“假”。從而給判斷帶來很大的靈活性。在C99中,增加了_Bool類型,并增加了頭文件,在其中定義了宏bool、true和false,用true存儲(chǔ)1,

23、用false存儲(chǔ)0。第24頁/共150頁關(guān)系運(yùn)算與關(guān)系表達(dá)式 關(guān)系表達(dá)式和邏輯表達(dá)式是C語言中描述命題的兩種基本形式。 1. C語言的關(guān)系運(yùn)算符關(guān)系運(yùn)算是指對(duì)兩個(gè)表達(dá)式值的大小比較。C語言中提供有如下6個(gè)關(guān)系運(yùn)算符: (大于) =(大于或等于) (小于) =(小于或等于) =(等于)!=(不等于)后兩個(gè)(=和!=)的優(yōu)先級(jí)小于前4個(gè),但它們都低于純算術(shù)類,高于賦值類,并且它們結(jié)合方式都是從左向右的。例如: a+bc+d 應(yīng)理解為 (a+b)(c+d)第25頁/共150頁 2. 關(guān)系運(yùn)算符的值關(guān)系表達(dá)式的值只有兩個(gè):關(guān)系表達(dá)式成立,即為“真”(通常為1);關(guān)系表達(dá)式不成立,即為“假”(0)。例如

24、對(duì)于聲明: int x=2, y=3,z; 表達(dá)式 x=y 的值為0。而表達(dá)式 xy 的值為1。那末表達(dá)式 z=3-1=x+1=y+2 的值呢?在這個(gè)表達(dá)式中有賦值、關(guān)系、算術(shù)三種運(yùn)算。其中“賦值”的優(yōu)先級(jí)最低,其次為“關(guān)系”,“算術(shù)”的優(yōu)先級(jí)最高。因此,先進(jìn)行算術(shù)運(yùn)算得 z=2=3=5 然后計(jì)算2=3,其值為0(假),得 z=0=5 再計(jì)算0=5,值為1(真),故有z的值為1。第26頁/共150頁 應(yīng)當(dāng)注意:(1)表達(dá)式5278在數(shù)學(xué)上是不允許的,而在C中是允許的。按自左而右的結(jié)合求解: 52值為1; 17值為0; 08的值為0。 即整個(gè)關(guān)系表達(dá)式的值為0。(2)由于關(guān)系表達(dá)式的值是整型數(shù)0

25、或1,故也可以將其看成是一種整型表達(dá)式。例如,若有: int i=1, j=7,a; a=i+(j%4!=0); 由于j%4的值為3,而3!=0的值為1(真),故a的值為2。但這種表達(dá)式的含義不易被理解,初學(xué)時(shí)不宜多用。第27頁/共150頁(4)在判定兩個(gè)浮點(diǎn)數(shù)是否相等時(shí),由于存儲(chǔ)上的誤差,會(huì)得出錯(cuò)誤的結(jié)果。例如: 在數(shù)學(xué)上顯然應(yīng)該是一個(gè)恒等式,但由于1.0/3.0得到的值的有效位數(shù)是有限的,并不等于0.3333333333333,因此上面關(guān)系表達(dá)式的值為0(假),并不為1(真)。所以應(yīng)避免對(duì)兩個(gè)實(shí)數(shù)表達(dá)式作“相等”或“不相等”的判別。上式可改寫為: fabs (1.0/3.0* 3.0-1.

26、0)1e-5 fabs是求絕對(duì)值函數(shù)。只要1.0/3.0與1.0之間的差小于10-5(或一個(gè)其它的很小的數(shù)),就認(rèn)為與1.0相等。(5)要表示x在區(qū)間a,b中,在數(shù)學(xué)中使用表達(dá)式axb。但在C語言中使用表達(dá)式“a=x=b”會(huì)與原來的意義不同。假設(shè)a=0;b=0.5。若x=0.3,則執(zhí)行a=x=b時(shí)先求出“a=x”的值得1(真),再計(jì)算“1=b”得0(假)。因此,為了判別x是否在a,b范圍內(nèi),應(yīng)寫成: a=x & x=b “&”是下面將要介紹的邏輯運(yùn)算符“與”。a=x的值為1(真)且x=b的值亦為1(真),則整個(gè)表達(dá)式的值為1(真)。第28頁/共150頁邏輯運(yùn)算與邏輯表達(dá)式1.

27、邏輯運(yùn)算的基本概念 C語言有三個(gè)邏輯運(yùn)算符,它們是: & (邏輯與) |(邏輯或) !(邏輯非) 為了說明“與”、“或”、“非”的概念,先看一下圖3.8。 當(dāng)圖3.8(a)中的開關(guān)a和b都合上時(shí),燈泡c才亮。這就是“與”的概念,即只有a和b均為真時(shí),c才為“真”(1)。在C語言中,“與”運(yùn)算用“&”運(yùn)算符表示。下面是邏輯“與”的簡單應(yīng)用:if (a & b)c=1;elsec=0; 圖3.8(b)中c燈亮的條件是a“或”b之一合上(二者都合上也行),即至少a或b之一為“真”(1)。在C語言中,“或”運(yùn)算用“|”運(yùn)算符表示。下面是邏輯“或”的簡單應(yīng)用:if (a|b)c=

28、1;else c=0;第29頁/共150頁ABBAA(a)邏輯)邏輯“與與” (b)邏輯)邏輯“或或” (c)邏輯)邏輯“非非” 圖圖3.8 三個(gè)基本邏輯運(yùn)算三個(gè)基本邏輯運(yùn)算 第30頁/共150頁 從圖3.8(c)中可以看出,當(dāng)a合上時(shí)c燈不亮,只有a不合上燈才亮,即a“非”,c才為“真”(1)。在C語言中,“非”運(yùn)算用“!”運(yùn)算符表示。下面是邏輯“非”的簡單應(yīng)用: if (!a)c=1;elsec=0; &和|是二元運(yùn)算符,結(jié)合方向?yàn)樽宰笾劣遥?為一元運(yùn)算符, 結(jié)合方向?yàn)樽杂抑磷蟆?amp;和|的優(yōu)先級(jí)低于關(guān)系運(yùn)算符,而!的優(yōu)先級(jí)高于關(guān)系運(yùn)算符。例如表達(dá)式!31,應(yīng)先計(jì)算!3,得0;

29、再計(jì)算01,得0。第31頁/共150頁 2. 常用的邏輯運(yùn)算規(guī)律 邏輯運(yùn)算中有很多有趣的規(guī)律。例如:(1) 在一個(gè)&表達(dá)式中,若&的一端為0,則不必再計(jì)算另一端,該表達(dá)式的值肯定為0(在C語言中由于&是從左向右結(jié)合的,所以只考慮左端,即當(dāng)&號(hào)的左端為0時(shí),不再計(jì)算其右端),可以把它記為: 0 & a=0(2) 在一個(gè)|表達(dá)式中,若|的一端為1,則不必計(jì)算另一端,該|表達(dá)式的值必為1?,F(xiàn)把它記為: 1|a=1 諸如此類關(guān)于表達(dá)式的值的規(guī)律有如下一些: 0|a=a1&a=a1|a=10&a=0 a|!a=1 0&!a=0 以及 a|a

30、=aa&a=a!(a|b)=!a&!b!(a&b)=!a|!b !(!a)=a記住這些規(guī)律,能使復(fù)雜的邏輯運(yùn)算簡化、清晰。第32頁/共150頁 表3.1為基本邏輯運(yùn)算的真值表:兩個(gè)操作數(shù)為不同的邏輯值時(shí),基本邏輯運(yùn)算的運(yùn)算結(jié)果。 ab!a!ba|ba&bTTFFTTTFFTFTFTTFFTFFTTFF表表3.1 基本邏輯運(yùn)算的真值表基本邏輯運(yùn)算的真值表 第33頁/共150頁選擇型程序描述了求解規(guī)則:在不同的條件下所應(yīng)進(jìn)行的相應(yīng)操作。 下面分別介紹C語言中用來實(shí)現(xiàn)選擇結(jié)構(gòu)的三種語句。結(jié)構(gòu)的應(yīng)用 if (表達(dá)式) 語句1 else 語句2ifelse構(gòu)造了一種二路分

31、支選擇結(jié)構(gòu),它具有如下格式:這里,語句1和語句2就是兩路分支。執(zhí)行這個(gè)結(jié)構(gòu),首先對(duì)表達(dá)式進(jìn)行判斷,若為“真”(非零),就執(zhí)行if分結(jié)構(gòu)(語句1);否則(值為0),就執(zhí)行else分結(jié)構(gòu)(語句2)。if (表達(dá)式)語句1else語句2第34頁/共150頁例3.3 求一個(gè)數(shù)的絕對(duì)值。 設(shè)有任意數(shù)x,它的絕對(duì)值為 判斷內(nèi)容:x0是否成立。 兩路分支:x=x (當(dāng)x0) ; x= -x (當(dāng)x0 ) C函數(shù)如下:-x (x0)x (x0)x=/* 文件名:文件名:ex030301.c */* 求絕對(duì)值求絕對(duì)值 */double abstr (double x)if (x0.0)x=-x;elsex=x;

32、return (x);第35頁/共150頁下面是函數(shù)abstr被調(diào)用執(zhí)行的情況:#include int main(void)double a, abstr (double a);printf (Enter real number a please:);scanf (%1f,&a);printf (abstr(%1f)=%1 fn, a, abstr (a);rerurn 0;運(yùn)行情況如下 Enter real number a please: -98.7654 abstr (-98.765400)=98.765400第36頁/共150頁C語言還允許使用缺省else分結(jié)構(gòu)的ifelse

33、結(jié)構(gòu)。其形式為:如上述abstr()函數(shù)可以改寫為:double abstr (double x)if (x0.0)x=-x;return (x); 這種結(jié)構(gòu)稱為不平衡if結(jié)構(gòu)。它不如平衡的if結(jié)構(gòu)容易理解和清晰。下面看一個(gè)稍復(fù)雜的例子。if (表達(dá)式)語句第37頁/共150頁例3.4 三數(shù)中取大數(shù)。 有人按照?qǐng)D3.9所示的算法邏輯設(shè)計(jì)了下面的函數(shù):/* 文件名:文件名:ex030401.c */* 三數(shù)取大三數(shù)取大 */float max3 (float x, float y, float z)float max=x;if (zy)if (zx)max=z;elseif (yx)max=y;

34、return (max);然而,它被main()函數(shù)調(diào)用時(shí)的的一次運(yùn)行情況如下: Enter 3 real numbers a,b,c:12.34 5.67 34.56 The max is 12.300000這就因?yàn)槭褂貌黄胶鈏f結(jié)構(gòu)時(shí),沒有搞清ifelse結(jié)構(gòu)的語法規(guī)則。第38頁/共150頁zxmax=z(空)max = x假真yxmax=y(空)真假zy真假return(max)圖圖3.9 例例3.4的設(shè)計(jì)者使用的算法的設(shè)計(jì)者使用的算法 第39頁/共150頁C語言不規(guī)定程序的書寫格式,允許以靈活的格式書寫。在編譯時(shí)完全不考慮程序的書寫格式,只憑語法規(guī)則來確定程序中的邏輯關(guān)系。當(dāng)程序中存在

35、嵌套的ifelse結(jié)構(gòu)時(shí),由后向前使每一個(gè)else都與其前面的最靠近它的if配對(duì)。如果一個(gè)else的上面又有一個(gè)未經(jīng)配對(duì)的else,則先處理上面的(內(nèi)層的)else的配對(duì)。這樣反復(fù)配對(duì),直到把全部else用完為止。按照這一規(guī)則,例3.4中的函數(shù)max3實(shí)際上具有如圖3.10所示的邏輯關(guān)系。顯然,這是一個(gè)錯(cuò)誤的算法,因?yàn)楫?dāng)x,y,z分別為(2,3,1)和(1,3,2)時(shí),結(jié)果是錯(cuò)誤的。(空)zxmax=z假真yxmax=y真假max = xzy真假return(max)圖圖3.10 例例3.4程序?qū)嶋H使用的算法程序?qū)嶋H使用的算法 第40頁/共150頁 通過這個(gè)例子可以看到:(1) 不平衡的ife

36、lse結(jié)構(gòu)會(huì)增加閱讀和理解程序的困難。(2) 正確的縮進(jìn)格式(即鋸齒形書寫格式)可以幫助人們理解程序,但錯(cuò)誤的縮進(jìn)格式反而會(huì)使人迷惑。(3) 不要太相信自己的判斷,要嚴(yán)格按語法關(guān)系檢查程序。在不易弄清的地方可以加花括號(hào)來保證自己構(gòu)思的邏輯關(guān)系的正確性。如上述程序可以改寫為:float max3 (float x, float y, float z) float max=x;if (zy)if (zx)max=z;elseif (yx)max=y;return (max);第41頁/共150頁例3.5 求一元二次方程ax2+bx+c=0的根。 算法設(shè)計(jì):一元二次方程式的根有下列情況: 當(dāng)a=0,

37、b=0時(shí),方程無解; 當(dāng)a=0,b0時(shí),方程只有一個(gè)實(shí)根-c/b; 當(dāng)a0時(shí),方程的根為x=(-bb2-4ac)/(2*a)。其中, 當(dāng)b2-4ac0時(shí)有兩個(gè)實(shí)根;當(dāng)b2-4ac0時(shí),有兩個(gè)虛根。圖3.12為上述算法的N-S圖表示,它把上述邏輯關(guān)系表示得更為清晰。b=0輸出“無解”輸出單根:x=-c/b假真disc0輸出兩復(fù)數(shù)根輸出兩實(shí)根真假a=0真假 disc=b*b - 4*a*c圖圖3.12 求一元二次方程根的算法求一元二次方程根的算法第42頁/共150頁/* 文件名:文件名:ex030501.c */* 求解一元二次方程求解一元二次方程 */include void solv_quad

38、r_equa (float a, float b, float c)if (a=0.0)if (b=0.0)printf (no answer due to input errorn);elseprintf (the single root is %fn, -c/b);elsedouble disc, twoa, term1, term2;disc=b*b-4*a*c;twoa=2*a;term1=-b/twoa;term2=sqrt (fabs (disc)/twoa;if (disc0.0printf (complex root:n real part=%f,imag part=%fn,

39、term1, term2);elseprintf (real root:n root1=%f, root2=%fn,term1+term2, term1-term2);由此N-S圖可以編寫出以下的函數(shù):第43頁/共150頁程序第2行第一個(gè)單詞void表示函數(shù)solv_quadr_equa的類型為“空類型”,即該函數(shù)無返回值,因?yàn)榍蟪龅姆匠探舛际窃趫?zhí)行該函數(shù)時(shí)輸出的,不需要將方程解帶回主程序中輸出。所以函數(shù)值為“空”。程序solv_quadr_equa 的第15行中fabs是一個(gè)標(biāo)準(zhǔn)數(shù)學(xué)函數(shù)名,輸出一個(gè)實(shí)數(shù)的絕對(duì)值。請(qǐng)讀者自己編寫出測(cè)試此函數(shù)的main函數(shù)。第44頁/共150頁結(jié)構(gòu)的應(yīng)用if(表

40、達(dá)式1)if-else if是一種多分支選擇結(jié)構(gòu),用流程圖描述如圖3.13所示,用N-S圖描述如圖3.14所示,C語言中的格式如下:if(表達(dá)式1) 語句1else if(表達(dá)式2) 語句2else if(表達(dá)式n) 語句nelse語句n+1第45頁/共150頁真假表達(dá)式1表達(dá)式2表達(dá)式n語句n+1語句n語句2語句1真真假假圖圖3.13 if-else if結(jié)構(gòu)的流程圖描述結(jié)構(gòu)的流程圖描述第46頁/共150頁圖圖3.14 else if結(jié)構(gòu)的結(jié)構(gòu)的N-S圖描述圖描述語句1語句2語句3真假表達(dá)式1假真表達(dá)式2真假表達(dá)式3第47頁/共150頁例3.6 根據(jù)百分制分?jǐn)?shù)決定成績的等級(jí): 80分以上為A

41、級(jí); 70分及以上,80分以下,B級(jí); 60分及以上,70分以下,C級(jí); 60分以下,D級(jí)。圖3.15為用if-else if結(jié)構(gòu)描述的上述規(guī)則。真假score=80score=70等級(jí)A真假輸入scorescore=60等級(jí)B等級(jí)D等級(jí)C圖圖3.15 根據(jù)百分制分?jǐn)?shù)決定成績的等級(jí)根據(jù)百分制分?jǐn)?shù)決定成績的等級(jí)第48頁/共150頁程序如下:/* 文件名:文件名:ex031701.c */* 按成績分等按成績分等 */include int main(void)float score;printf(“Input a scre:”);scanf(“%f”,&score);if (score

42、= 80)printf (%f is An,score);else if (score = 70)printf (%f is Bn,score);else if (score = 60)printf (%f is Cn,score);elseprintf (%f is Dn,score);return 0;第49頁/共150頁可以看到,if-else if是通過一連串的判斷,來尋找問題的解。它排列了一系列操作,每一種操作都是在相應(yīng)的條件下才能執(zhí)行的。該結(jié)構(gòu)開始執(zhí)行后,便依次去對(duì)各個(gè)條件進(jìn)行判斷測(cè)試,符合某一條件,則轉(zhuǎn)去執(zhí)行該條件下的操作,其它部分將被跳過;如無一條件為真,就執(zhí)行最后一個(gè)else

43、所指定的操作。這個(gè)else可以看作“其它”。若最后一個(gè)else不存在,并且所有條件的測(cè)試均不成功,則該else if結(jié)構(gòu)將不執(zhí)行任何操作。第50頁/共150頁結(jié)構(gòu)的應(yīng)用 switch是一種多分支選擇結(jié)構(gòu),其形式如右。 switch結(jié)構(gòu)也稱標(biāo)號(hào)分支結(jié)構(gòu),它用花括號(hào)括起了一系列case子結(jié)構(gòu)。每個(gè)case子結(jié)構(gòu)都以一個(gè)常量表達(dá)式作為標(biāo)志的標(biāo)號(hào),并按照下面的規(guī)則匹配:計(jì)算switch的判斷表達(dá)式,并以此值去依次找與之相等的case標(biāo)號(hào)值,找到后就將流程轉(zhuǎn)到該標(biāo)號(hào)處,執(zhí)行后面各語句;如果找不到符合的case子結(jié)構(gòu),就只執(zhí)行default子結(jié)構(gòu)中的語句序列。default子結(jié)構(gòu)對(duì)于switch結(jié)構(gòu)不是必

44、須的。當(dāng)沒有default子結(jié)構(gòu),并且沒有相符合的case時(shí),該switch結(jié)構(gòu)就不被執(zhí)行。switch(表達(dá)式表達(dá)式)case 常量表達(dá)式常量表達(dá)式1:語句序列語句序列1case 常量表達(dá)式常量表達(dá)式2:語句序列語句序列2case 常量表達(dá)式常量表達(dá)式n:語句序列語句序列ndefault:語句序列語句序列n+1第51頁/共150頁請(qǐng)注意如果switch的判斷表達(dá)式的值與case常量表達(dá)式i的值相等(稱為匹配),在執(zhí)行后面的語句序列i之后,并不立即退出switch結(jié)構(gòu),而是繼續(xù)執(zhí)行語句序列i+1,語句序列i+2,語句序列n語句序列n+1如圖3.16所示,這種流程往往不是編程者所希望的。編程者希

45、望在執(zhí)行匹配的常量表達(dá)式后面的語句序列 i 之 后 , 應(yīng) 立 即 退 出switch結(jié)構(gòu)。為了解決這一問題,可以在各語句序列后面加一條break語句,使流程脫離switch結(jié)構(gòu)。如圖3.17所示。表達(dá)式語句序列1常量表達(dá)式1:語句序列2常量表達(dá)式2:語句序列i常量表達(dá)式i:語句序列n常量表達(dá)式n:語句序列n+1default圖圖3.16 switch3.16 switch控制結(jié)構(gòu)控制結(jié)構(gòu)1 1第52頁/共150頁這里,break語句的作用是中斷該switch結(jié)構(gòu),即將流程轉(zhuǎn)出switch結(jié)構(gòu)。所以,執(zhí)行switch結(jié)構(gòu)的就相當(dāng)于只執(zhí)行與判斷表達(dá)式相匹配的一個(gè)case子結(jié)構(gòu)中的語句。其實(shí),可以

46、將break看作為語句序列中必要的成分(位置在語句序列中的最后)。 switch(表達(dá)式表達(dá)式)case 常量表達(dá)式常量表達(dá)式1:語句序列語句序列1break;case 常量表達(dá)式常量表達(dá)式2:語句序列語句序列2break;case 常量表達(dá)式常量表達(dá)式n:語句序列語句序列nbreak;default:語句序列語句序列n+1break;圖圖3.17 switch3.17 switch控制結(jié)構(gòu)控制結(jié)構(gòu)2 2表達(dá)式語句序列1常量表達(dá)式1:語句序列2常量表達(dá)式2:語句序列i常量表達(dá)式i:語句序列n常量表達(dá)式n:語句序列n+1defaultbreak;break;break;break;break;第

47、53頁/共150頁例3.7 將一個(gè)月份數(shù)字轉(zhuǎn)換成英文月份名稱。 用函數(shù)實(shí)現(xiàn)這個(gè)功能如下:/* 文件名:文件名:ex030701.c */* 輸出月份名稱輸出月份名稱 */void MonthName(int month)(switch (month)case 1: priontf(“Januaryn”);break;case 2: priontf(“Februaryn”);break;case 3: priontf(“Marchn”);break;case 4: priontf(“Apriln”);break;case 5: priontf(“Mayn”);break;case 6: prio

48、ntf(“Junen”);break;case 7: priontf(“Jaulyn”);break;case 8: priontf(“Augustn”);break;case 9: priontf(“Septembern”);break;case 10: priontf(“Octobern”);break;case 11: priontf(“Novembern”);break;case 12: priontf(“Decembern”);break;default: priontf(“Illegal monthn”);break;return;第54頁/共150頁這個(gè)例子中,每一個(gè)case子結(jié)

49、構(gòu)的最后一個(gè)語句都是break。下面的例子中,是部分case子結(jié)構(gòu)中有break語句。例3.8 測(cè)試是數(shù)字、空白還是其它字符的函數(shù)(假設(shè)測(cè)試的對(duì)象只限于以上幾種字符)。/* 文件名:文件名:ex030801.c */* 測(cè)試字符類型測(cè)試字符類型 */int test_char (int c)switch (c)case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:printf (its a digit n);break;case :case n:case t:printf (it s a whiten);br

50、eak;default:printf (it s a charn);break;第55頁/共150頁這個(gè)函數(shù)的執(zhí)行過程如下:switch的條件表達(dá)式是一個(gè)已有整數(shù)值的c(今設(shè)c=8),于是從上至下找各case后的常數(shù)0,1,2,3,4,5,6,7,8,于是從case 8入口開始執(zhí)行下面的語句(采用了結(jié)構(gòu)1)。case 8后面沒有語句,就執(zhí)行case 9后面的printf函數(shù)語句,然后遇到break語句時(shí)跳出switch結(jié)構(gòu)。當(dāng)測(cè)試都失敗時(shí),即default以上的各case都不匹配,default則囊括了“除上述各case之外的一切情形”,于是執(zhí)行default子結(jié)構(gòu),直到遇到break退出sw

51、itch結(jié)構(gòu)。從語法上講,default子結(jié)構(gòu)中的break語句并不是必須的,執(zhí)行完default子結(jié)構(gòu)中的各語句后,則后面已無可執(zhí)行的語句了,會(huì)自動(dòng)退出switch結(jié)構(gòu)。這里使用了一個(gè)break語句是為了排列上的整齊及理解上的方便。default子結(jié)構(gòu)考慮了各case所列出的情形以外的其它情形。這樣就能在進(jìn)行程序設(shè)計(jì)時(shí),把出現(xiàn)頻率低的特殊情形寫在case的后面,而將其余情況寫在default后面作“統(tǒng)一處理”。如果只考慮對(duì)個(gè)別情況的處理,則可將各個(gè)情況分別寫在各個(gè)case的后面,此時(shí)default子結(jié)構(gòu)可以省略。第56頁/共150頁 使用switch結(jié)構(gòu)須注意以下幾點(diǎn):(1) 一個(gè)switc

52、h結(jié)構(gòu)的執(zhí)行部分是一個(gè)由一些case子結(jié)構(gòu)與一個(gè)可缺省的default子結(jié)構(gòu)組成的復(fù)合語句,它們位于一對(duì)花括號(hào)之中。(2) switch的判斷表達(dá)式只能對(duì)整數(shù)求值,可以使用字符或整數(shù),但不能使用浮點(diǎn)表達(dá)式。case表達(dá)式應(yīng)當(dāng)是整型常數(shù)表達(dá)式,不能含有變量與函數(shù)的常數(shù)表達(dá)式。例如可以是:case 3+4:但不允許寫為:int x=3,y=4;switch (z)case x+y:第57頁/共150頁 (3) 一個(gè)switch結(jié)構(gòu)中不可以出現(xiàn)兩個(gè)具有相同值的常量表達(dá)式。例如: case 3+2: case 8-3: 是不允許的。(4)switch的匹配測(cè)試,只能測(cè)試是否相等,不能測(cè)試關(guān)系或邏輯。(

53、5)C89要求C編譯系統(tǒng)應(yīng)當(dāng)實(shí)現(xiàn) 一個(gè)switch最少可以包含257個(gè)case子結(jié)構(gòu),而C99要求最少支持1023個(gè)case子結(jié)構(gòu)。(6)switch結(jié)構(gòu)允許嵌套。第58頁/共150頁/* 文件名:文件名:ex030901.c */* 聯(lián)想猜詞游戲聯(lián)想猜詞游戲 */include stdio.hint main(void)int c;c=getchar(); getchar(); /* 為接收一個(gè)字符,再接收一為接收一個(gè)字符,再接收一個(gè)分隔符個(gè)分隔符換行或空格換行或空格*/例3.9 聯(lián)想猜詞游戲 這個(gè)游戲是:游戲者心中想好一個(gè)單詞,并先在鍵盤上輸入第1個(gè)字母,然后讓計(jì)算機(jī)猜所選的是哪個(gè)單詞;如

54、果計(jì)算機(jī)顯示出的單詞不只一個(gè),游戲者就要再輸入第2個(gè)字母,如此操作,知道計(jì)算機(jī)猜出這個(gè)單詞或得出“猜不出”的結(jié)果為止。 下面的程序以猜“計(jì)算機(jī)語言名稱”為例。第59頁/共150頁switch (c)case a:case A:printf (Ada, Algol?n);c=getchar(); getchar();switch (c)case d:case D:printf (Ada n);break;case l:case L:printf (Algol n);break;default:printf (input errorn);break;break;case b:case B:prin

55、tf (Basic, BCDL?n);c=getchar(); getchar();switch (c)case a:case A:printf (Basicn);break;case c:case C:printf (BCDLn);break;default:printf (I am sorry!n);break;break;第60頁/共150頁case c:case C:printf (C,Cobol,C+,C#? n);c=getchar(); getchar();switch (c)case c:case C:printf (Cn);break;case o:case O:printf

56、 (Coboln);break;case +:printf (C+n);break;case #:printf (C#n);break;default:printf (I am sorry!n);break;break;default:printf (I am sorry!n);break;return 0;這是一個(gè)簡單的switch嵌套。輸入2個(gè)字母后就可找出唯一的單詞。如果單詞量大而且兩個(gè)字母還不能區(qū)分出單詞時(shí),嵌套層次就要增加,程序也就復(fù)雜了。第61頁/共150頁條件表達(dá)式 條件表達(dá)式也稱問號(hào)表達(dá)式,它的一般形式為:表達(dá)式1?表達(dá)式2:表達(dá)式3它的操作過程為:若表達(dá)式的值為真(非0),則

57、以表達(dá)式2的值作為該條件表達(dá)式的值;否則取表達(dá)式3的值作為該條件表達(dá)式的值。第62頁/共150頁例3.10 計(jì)算a+b的值。/* 文件名:文件名:ex031001.c */* 計(jì)算絕對(duì)值計(jì)算絕對(duì)值 */#include int main(void) /*計(jì)算計(jì)算a+b的值的值*/float a,b;printf (input 2 reals please:);scanf (%f%f,&a,&b);printf (n%f+%f=%f,a,b,b=0?a+b:a-b);return 0;第63頁/共150頁運(yùn)行情況如下:input 2 reals please: 10-9010.0

58、00000+-90.000000=100.000000printf()函數(shù)中b=0? a+b a-b,當(dāng)b0(b為正值)時(shí),取值a+b;當(dāng)b0(b為負(fù))時(shí),取值a-b。條件運(yùn)算符“?:”共要求三個(gè)運(yùn)算量,是C語言中唯一的三元運(yùn)算符。第64頁/共150頁例3.11 輸入兩數(shù),輸出大者。/* 兩數(shù)中取大兩數(shù)中取大 */* 文件名:文件名:ex031101.c */#include int main(void)float a,b, max;printf (input 2 reals please:);scanf (%f%f,&a,&b);max=ab?a b;printf (The

59、max is %fn, max);return 0;運(yùn)行情況如下:input 2 reals please: -100 89The max is 89.000000第65頁/共150頁因?yàn)闂l件運(yùn)算符的優(yōu)先級(jí)很低,僅僅比賦值操作符的級(jí)別高。其結(jié)合方式與賦值操作一樣是從右至左的。因此,表達(dá)式max=ab? a b相當(dāng)于:max=(ab?a:b);還須注意,C語言程序設(shè)計(jì)中,要求盡量避免使用“多余的臨時(shí)變量”,盡量把程序表述得簡潔。如上述程序中可以省去一個(gè)變量max,寫為:#include int main(void)float a,b;printf (input 2 relas please:);

60、scanf (%f%f,&a,&b);printf (The max is %fn,ab?a:b);return 0;第66頁/共150頁 迭代與窮舉算法采用循環(huán)(或稱重復(fù))結(jié)構(gòu)是計(jì)算機(jī)程序的一個(gè)重要特征。計(jì)算機(jī)運(yùn)算速度快,最宜于用于重復(fù)性的工作。在程序設(shè)計(jì)時(shí),人們也總是把復(fù)雜的不易理解的求解過程轉(zhuǎn)換為易于理解的操作的多次重復(fù)。這樣,一方面可以降低問題的復(fù)雜性,減低程序設(shè)計(jì)的難度,減少程序書寫及輸入的工作量;另一方面可以充分發(fā)揮計(jì)算機(jī)運(yùn)算速度快、能自動(dòng)執(zhí)行程序的優(yōu)勢(shì)。在循環(huán)算法中,窮舉與迭代是兩類具有代表性的基本應(yīng)用。這一節(jié)的主要內(nèi)容就是引導(dǎo)讀者如何用C語言的三種循環(huán)結(jié)構(gòu)來實(shí)現(xiàn)這兩種基本算法。第67頁/共150頁1. 迭代 迭代是一個(gè)不斷用新值取代變量的舊值,或由舊值遞推出變量的新值的過程。例3.12 人口增長問題。 按年0.2%的增長速度,現(xiàn)有13億人,10年后將有多少人? 設(shè)現(xiàn)人口數(shù)為

溫馨提示

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

評(píng)論

0/150

提交評(píng)論