Matlab分支語句和編程設(shè)計(jì)_第1頁
Matlab分支語句和編程設(shè)計(jì)_第2頁
Matlab分支語句和編程設(shè)計(jì)_第3頁
Matlab分支語句和編程設(shè)計(jì)_第4頁
Matlab分支語句和編程設(shè)計(jì)_第5頁
已閱讀5頁,還剩64頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

2023年2月4日第1頁第4講分支語句和編程設(shè)計(jì)MATLABR2010a基礎(chǔ)教程清華大學(xué)出版社自上而下的編程方法簡介關(guān)系運(yùn)算符和邏輯運(yùn)算符選擇結(jié)構(gòu)(分支語句)在前面的章節(jié)中,我們開發(fā)了幾個(gè)完全運(yùn)轉(zhuǎn)的MATLAB程序。但是這些程序都十分簡單,包括一系列的MATLAB語句,這些語句按照固定的順序一個(gè)接一個(gè)的執(zhí)行。像這樣的程序我們稱之順序結(jié)構(gòu)程序。它首先讀取輸入,然后運(yùn)算得到所需結(jié)果,打印出結(jié)果,并退出。至于要多次重復(fù)運(yùn)算程序的某些部分是沒有辦法的,也不能根據(jù)輸入的值,有選擇地執(zhí)行程序的某些部分。在下面的兩章中,將向大家介紹大量的MATLAB語句,這些語句允許我們來控制語句的執(zhí)行順序。有兩大類控制順序結(jié)構(gòu):選擇結(jié)構(gòu),用選擇執(zhí)行特定的語句;循環(huán)結(jié)構(gòu),用于重復(fù)執(zhí)行特定部分的代碼。循環(huán)結(jié)構(gòu)我們將會(huì)在下節(jié)課討論。隨著選擇和循環(huán)介紹,我們的程序也將變得復(fù)雜,對于解決問題來說,將會(huì)變得簡單。為了幫助大家避免在編程過程中出現(xiàn)大量的錯(cuò)誤,我們將向大家介紹正式的編程步驟,即自上而下的編程方法。我們也會(huì)向大家介紹一些普通的算法開發(fā)工具即偽代碼。2023年2月4日第2頁一自上而下的編程方法簡介當(dāng)遇到一個(gè)新問題時(shí),我們的心里會(huì)自然而然的產(chǎn)生這樣的想法:馬上坐在計(jì)算機(jī)前,開始編程,而不用浪費(fèi)大量的時(shí)間思考我們所要解決的問題是什么?用這種不切實(shí)際的想法來編一些非常小的程序可能會(huì)成功。但在現(xiàn)實(shí)中,問題可能會(huì)非常的大,程序員再用這種方法編程將會(huì)陷入困境。對于一個(gè)大的程序來說,在編寫代碼之前你要通盤的思考你所要面臨的問題和解決的方法。在本節(jié)中,我們將向大家介紹正式的編程設(shè)計(jì)步驟,然后應(yīng)用這個(gè)步驟來編寫所有的大的應(yīng)用程序。對于我們所遇到一些簡單的例子來說,這個(gè)步驟好像有些畫蛇添足。但是當(dāng)我們解決的問題變得越來越大的時(shí)侯,這個(gè)步驟將會(huì)變得異常重要。2023年2月4日第3頁假設(shè)你是在工廠工作的工程師,為了解決某些問題,你要編寫一個(gè)程序。你如何開始呢?工作中遇到的大多數(shù)困難都是對所要解決問題的理解。一旦你真正理解了問題,你就會(huì)把這個(gè)問題分解成許多小的問題,更加易于管理的小塊,然后逐一解決某一個(gè)小塊。自上而下的編程方法是我們正規(guī)編程設(shè)計(jì)的基礎(chǔ)。我們現(xiàn)在向大家介紹這些在下圖中說明的步驟細(xì)節(jié)。步驟如下:2023年2月4日第4頁2023年2月4日第5頁1.清晰地陳述你所要解決的問題編寫的程序大多數(shù)情況下要滿足一些感覺上的需要,但這種需要不一定能夠被人清晰地表達(dá)出來。例如,用戶需要一個(gè)解線性方程組的表達(dá)式。像這樣的要求就不夠清楚,程序員就很難編出一個(gè)使他滿意的程序。他必須弄清楚要有多少問題需要解決?在這些方程式中有沒有對稱的形式使我們的開發(fā)變得簡單?程序設(shè)計(jì)者必須和使用者討論所需的程序,他們必須要對完成的任務(wù)有一個(gè)精確細(xì)致的描述。對問題清晰的描述可以防止誤解,并且能夠幫助程序員合理的組織他的思想。上面的例子對問題合適的陳述應(yīng)為:設(shè)計(jì)一個(gè)用于解決聯(lián)立線性方程組的程序,這些方程中未知數(shù)的系數(shù)為實(shí)數(shù),最多有20個(gè)未知數(shù)。2023年2月4日第6頁2.定義程序所需的輸入量和程序所產(chǎn)生的輸出量指定輸入量和輸出量,只有這樣新的程序才能適應(yīng)全過程計(jì)劃。在這個(gè)例子中方程式的系數(shù)可能有其預(yù)先存在的順序,我們的新程序必須能按照順序讀取它們。相似地,也需要產(chǎn)生出這個(gè)程序所要求的結(jié)果,即輸出量,我們還要以一定的格式打印出來。2023年2月4日第7頁3.設(shè)計(jì)你的程序得以實(shí)現(xiàn)的算法算法是指為某個(gè)問題找到答案一步接一步的程序。在這個(gè)階段自上而下的編程方法發(fā)揮了作用。編程設(shè)計(jì)者開始對這個(gè)問題進(jìn)行邏輯劃分,把它逐步分解為一個(gè)又一個(gè)子工作。這個(gè)過程叫做分解(decomposition)。如果一些子工作還是比較大,設(shè)計(jì)者還可以把他它分解成更小的塊。這個(gè)過程將會(huì)繼續(xù)到問題被分解成許多簡單且易理解的小塊為止。在問題被分解成小塊之后,每一個(gè)小塊要被進(jìn)一步的求精,這個(gè)過程叫做逐步求精(stepwiserefinement)。在這個(gè)過程中,設(shè)計(jì)者開始于對本小塊代碼總括性的描述,然后開始一步一步地定義所需的函數(shù),越來越具體,直到他能夠轉(zhuǎn)化為MATLAB語句。逐步求精的過程中,我們要用到的偽代碼將會(huì)在下節(jié)為大家介紹。在算法開發(fā)過程中,這個(gè)方法是非常有用的。如果設(shè)計(jì)者真正理解了解決問題這個(gè)些步驟,他將會(huì)對問題進(jìn)行分解和逐步求精。2023年2月4日第8頁4.把算法轉(zhuǎn)化為代碼如果分解和逐步求精的過程已經(jīng)順利完成,那么這一步將會(huì)異常地簡單。所有程序員都會(huì)將偽代碼一句一句地轉(zhuǎn)化為合適地MATLAB語句。2023年2月4日第9頁5檢測產(chǎn)生的MATLAB程序這一步是真正的攔路虎。首先,程序的每一部分將會(huì)被單獨(dú)地檢測,如果有可能的話,整個(gè)程序還要被檢測一遍。在我們檢測程序時(shí),我們必須證明所有合法輸入數(shù)據(jù)值都能夠正常運(yùn)行。用標(biāo)準(zhǔn)的輸入值檢測程序,看它是否產(chǎn)生了值。如果在一個(gè)程序中執(zhí)行的算法包含了不同的分支,你必須檢測每一個(gè)分支,以保證產(chǎn)生正確的答案。大程序在交付大眾使用之前,必須經(jīng)過一系列地檢測。檢測的第一步有時(shí)被稱為單元檢測(unittesting)。在單元檢測過程中,程序的子程序?qū)?huì)被獨(dú)立地檢測以證明它的正確性。當(dāng)單元檢測結(jié)束之后,這個(gè)程序?qū)⑦M(jìn)行一系列的組合,把獨(dú)立的子程序聯(lián)合產(chǎn)生出最后的程序。程序第一步的聯(lián)合通常只包括很少的子程序。通過組合這些子程序,經(jīng)常用于檢查子程序或函數(shù)之間的聯(lián)系。在一系列地組合過程中,越來越多的子程序被加了進(jìn)來,直到整個(gè)程序的完成。在每一次組合的過程中,每一個(gè)錯(cuò)誤都會(huì)被發(fā)現(xiàn)并在進(jìn)行下一次組合之前糾正過來。2023年2月4日第10頁在整個(gè)程序被組合之后,調(diào)試?yán)^續(xù)進(jìn)行。程序第一個(gè)版本我們通常稱之為“alpha版本”。程序員和其他有機(jī)會(huì)接近它的人可以想盡一切辦法應(yīng)用它,以發(fā)現(xiàn)其中的漏洞,然后改正之。當(dāng)許許多多大的錯(cuò)誤從程序中去除,一個(gè)新的版本出現(xiàn)了,我們稱之“beta版本”。beta版本就要公開地發(fā)行給天天需要這個(gè)程序工作的人。這些用戶使這個(gè)程序在不同的環(huán)境下,在不同的輸入條件下工作,會(huì)發(fā)現(xiàn)許多的錯(cuò)誤,并報(bào)告給程序員。當(dāng)這些錯(cuò)誤被更正后,這個(gè)程序就能夠發(fā)行給公眾使用了。因?yàn)槲覀儸F(xiàn)在一般接觸的程序都比較小,沒有必要進(jìn)行上述的大規(guī)模的檢測。但是我們會(huì)遵循基本的調(diào)試原則。2023年2月4日第11頁大程序典型地調(diào)試過程2023年2月4日第12頁程序設(shè)計(jì)的基本步驟:1.清晰地陳述出你要解決的問題。2.確定程序所需地輸入量和程序所產(chǎn)生的輸出量。3.為你的程序設(shè)計(jì)算法4.將算法轉(zhuǎn)化為MATLAB語句5.調(diào)試MATLAB程序2023年2月4日第13頁在大的編程項(xiàng)目中,花在編程序的時(shí)間是出奇的少。FrederickPBrooks在他的theMythicalMan-Month書中寫道,對于大的軟件工程來說,三分之一的時(shí)間花在計(jì)劃如何來做上(第一步到第三步),六分之一的時(shí)間花在編寫程序上,近一半的時(shí)間用來調(diào)試程序。而我們能做的只有壓縮調(diào)試用的時(shí)間。在計(jì)劃階段做好充分的準(zhǔn)備和在編程過程使用良好的編程習(xí)慣,這樣會(huì)大大降低我們調(diào)試所用的時(shí)間。好的編程習(xí)慣能減少出錯(cuò)的數(shù)量,也能使別人迅速地找出其中的錯(cuò)誤。2023年2月4日第14頁好的編程習(xí)慣

遵循上面的步驟編寫可靠,易理解的MATLAB程序。二偽代碼的應(yīng)用作為我們設(shè)計(jì)步驟的一部分,描述出你要執(zhí)行的算法是非常必要的。算法的描述有一種標(biāo)準(zhǔn)形式,能讓你和大家都能理解,這種描述將幫助你的內(nèi)容轉(zhuǎn)化為MATLAB代碼。我們用于描述算法的標(biāo)準(zhǔn)形式叫做構(gòu)造(constructs有時(shí)也稱structure)。用這些結(jié)構(gòu)描述出的算法,我們稱之為結(jié)構(gòu)化算法。當(dāng)在我們在MATLAB程序中執(zhí)行這個(gè)算法時(shí),產(chǎn)生的程序叫做結(jié)構(gòu)化程序。我們可以用偽代碼的形式建立算法的結(jié)構(gòu)。偽代碼是MATLAB和英語的混合體。和MATLAB一樣,它是結(jié)構(gòu)化的,一行表達(dá)一個(gè)明確的意思或代碼的片段,但每一行的描述用的是英語或其他人類語言。偽代碼的每一行都應(yīng)用普通簡單且易于理解的英語或中文描述。因?yàn)樾薷暮唵戊`活,所以偽代碼在開發(fā)算法的過程中非常的有用。因?yàn)閭未a給編輯器或字處理器(通常用于編寫MATLAB程序)的,而不需要其他的可視化功能。例如下面是例子的算法偽代碼2023年2月4日第15頁例(溫度轉(zhuǎn)換)設(shè)計(jì)一個(gè)MATLAB程序,讀取一個(gè)華氏溫度的輸入,輸出開爾文溫度。華氏溫度和開爾文溫度的轉(zhuǎn)換關(guān)系式可在物理學(xué)課本中找到。其關(guān)系式為:

2023年2月4日第16頁注意用向左指的箭頭←替代等號(hào)(=)指出一個(gè)值將存儲(chǔ)到對應(yīng)的變量中,這樣就避免了賦值號(hào)與等號(hào)的混淆。在把它們轉(zhuǎn)化為MATLAB代碼之前,偽代碼將有助于你思想的組織。2023年2月4日第17頁P(yáng)romptusertoentertemperatureindegreesFahrenheitReadtemperatureindegreesFahrenheit(temp_f)temp_kinkelvins←(5/9)*(temp_f-32)+273.15Writetemperatureinkelvins我們設(shè)計(jì)程序的步驟如下1.提示用戶鍵入華氏溫度值2.讀取輸入值3.通過關(guān)系式轉(zhuǎn)換為開氏溫度4.輸出結(jié)果,結(jié)束三

關(guān)系運(yùn)算符和邏輯運(yùn)算符選擇結(jié)構(gòu)的運(yùn)算由一個(gè)表達(dá)式控制的,這個(gè)表達(dá)式的結(jié)果只有true(1)和false(0)。有兩種形式的運(yùn)算符可以在MATLAB中關(guān)系得到true/false:關(guān)系運(yùn)算符和邏輯運(yùn)算符。跟C語言一樣,MATLAB沒有布爾型和邏輯數(shù)據(jù)類型。MATLAB把0值作為結(jié)果false,把所有的非0值作為結(jié)果ture。2023年2月4日第18頁1關(guān)系運(yùn)算符關(guān)系運(yùn)算符是指兩數(shù)值或字符操作數(shù)的運(yùn)算符,這種運(yùn)算將會(huì)根椐兩操作數(shù)的關(guān)系產(chǎn)生結(jié)果true或false。關(guān)系運(yùn)算的基本形式如下a1opa2其中a1和a2是算術(shù)表達(dá)式,變量或字符串,op代表中的關(guān)系運(yùn)算符中的一個(gè)。如果兩者的關(guān)系為真(true)時(shí),那么這個(gè)運(yùn)算將會(huì)返回1值;否則將會(huì)返回0值。2023年2月4日第19頁關(guān)系運(yùn)算符運(yùn)算符運(yùn)算==等于~=不等于>

大于>=大于或等于<

小于<=小于或等于2023年2月4日第20頁下面是一些關(guān)系運(yùn)算和它的結(jié)果運(yùn)算結(jié)果3<4

3<=4 3==4 3>4 4<=4 'A'<'B' 最后一個(gè)運(yùn)算得到的結(jié)果為1,是因?yàn)樽址g的求值要按照子母表的順序。2023年2月4日第21頁110011關(guān)系運(yùn)算符也可用于標(biāo)量與數(shù)組的比較如果和b=0,那么表達(dá)式a>b將會(huì)產(chǎn)生結(jié)果

2023年2月4日第22頁關(guān)系運(yùn)算符也可比較兩個(gè)關(guān)系運(yùn)算符,只要兩個(gè)數(shù)組具有相同的大小。表達(dá)式a>=b將會(huì)產(chǎn)生結(jié)果如果這個(gè)數(shù)組具有不同的大小,那么將會(huì)產(chǎn)生運(yùn)行時(shí)錯(cuò)誤。注意因?yàn)樽址畬?shí)際上是字符的數(shù)組,關(guān)系運(yùn)算符也比較兩個(gè)相同長度的字符串。如果它們有不同的長度,比較運(yùn)算將會(huì)產(chǎn)生一個(gè)錯(cuò)誤。等于關(guān)系運(yùn)算符由兩個(gè)等號(hào)組成,而賦值運(yùn)算符只有一個(gè)等號(hào)。它們是完全不同的兩個(gè)符號(hào),初學(xué)者極易混淆。符號(hào)==是一個(gè)比較運(yùn)算符,返回一個(gè)邏輯數(shù),而符號(hào)=是將等號(hào)右邊的表達(dá)式的值賦給左邊的變量。當(dāng)進(jìn)行比較運(yùn)算的時(shí)候,初學(xué)者經(jīng)常用誤用符號(hào)=。2023年2月4日第23頁常見編程錯(cuò)誤小心謹(jǐn)慎不要混淆了等于關(guān)系運(yùn)算符(==)和賦值運(yùn)算符(=)。在運(yùn)算的層次中,關(guān)系運(yùn)算在所有數(shù)學(xué)運(yùn)算的之后進(jìn)行。所以下面兩個(gè)表達(dá)式是等價(jià)的,均產(chǎn)生結(jié)果1。7+3<2+11(7+3)<(2+11)2023年2月4日第24頁2小心==和~=運(yùn)算符用這兩個(gè)運(yùn)算符比較兩個(gè)字符串他是安全的,不會(huì)出現(xiàn)錯(cuò)誤。但對兩個(gè)數(shù)字?jǐn)?shù)據(jù)的比較,將可能產(chǎn)生異想不到的錯(cuò)誤。兩個(gè)理論上相等的數(shù)不能有一絲一毫的差別,而在計(jì)算機(jī)計(jì)算的過程中出現(xiàn)了近似的現(xiàn)象,從而可能在判斷相等與不相等的過程中產(chǎn)生錯(cuò)誤,這種錯(cuò)誤叫做roundoff錯(cuò)誤。例如,考慮下面的兩個(gè)數(shù),兩者均應(yīng)等于0。2023年2月4日第25頁等于運(yùn)算符(==)如果兩變量值相同將會(huì)返回變量值1,如果不同將返回0。不等運(yùn)算符(~=)如果兩變量值不同則返回1,相則返回0。修正誤差a=0;b=sin(pi);因?yàn)檫@兩個(gè)數(shù)在理論上相等的,所以關(guān)系式a==b應(yīng)當(dāng)返回值1。但在事實(shí)上,MATLAB計(jì)算所產(chǎn)生的結(jié)果的是>>a=0;>>b=sin(pi);>>a==bans=0MATLAB報(bào)告了a和b不同因?yàn)樗a(chǎn)生了一個(gè)roundoff錯(cuò)誤,在計(jì)算中sin(pi)產(chǎn)生了結(jié)果1.2246×10-16而不是0。兩個(gè)理論上相等的值因?yàn)閞oundoff錯(cuò)誤而使之發(fā)生了細(xì)微的差別。2023年2月4日第26頁我們可以通過檢測兩數(shù)之間在一定的范圍內(nèi)是不是近似相等,在這個(gè)精確范圍內(nèi)可能會(huì)產(chǎn)生roundoff錯(cuò)誤。例如測試>>abs(a-b)<1.0E-14ans=1將會(huì)產(chǎn)生正確的結(jié)果,不管在a與b的計(jì)算中產(chǎn)不產(chǎn)生的roundoff錯(cuò)誤。2023年2月4日第27頁好的編程習(xí)慣在我們檢測兩數(shù)值是否相等時(shí)一定要小心,由于修正誤差可能會(huì)使兩個(gè)本來應(yīng)該相等的值不相等了。這時(shí)你可以在修正誤差的范圍內(nèi)判斷它是不是近似相等。3邏輯運(yùn)算符邏輯運(yùn)算符是聯(lián)系一個(gè)或二個(gè)邏輯操作數(shù)并能產(chǎn)生一個(gè)邏輯結(jié)果的運(yùn)算符。有三個(gè)二元運(yùn)算符:分別為AND,OR和異或運(yùn)算符,還有一個(gè)一元運(yùn)算符NOT。二元邏輯運(yùn)算的基本形式l1

opl2一元邏輯運(yùn)算的基本形式為op

l1l1和l2代表表達(dá)式或變量,op代表的邏輯運(yùn)算符。如果l1和l2的邏輯運(yùn)算關(guān)系為true,那么運(yùn)算將會(huì)返回值1,否則將會(huì)產(chǎn)生0。2023年2月4日第28頁邏輯運(yùn)算符&邏輯與|邏輯或xor邏輯與或~邏輯非2023年2月4日第29頁運(yùn)算的結(jié)果總結(jié)在真值表中,它向我們展示每一種運(yùn)算所有可能的結(jié)果。如果一個(gè)數(shù)的值不為0,那么MATLAB將把看作true,如果它為0,則其為false。所以~5的結(jié)果為0,~0的結(jié)果為1。2023年2月4日第30頁輸入與或異或非l1l2l1

&l2l1

|l2xor(l1,l2)~l1000001010111100110111100標(biāo)量和數(shù)組之間也可進(jìn)行邏輯運(yùn)算如果和b=0,那么表達(dá)式a&b將會(huì)產(chǎn)生結(jié)果

2023年2月4日第31頁兩數(shù)組之間也可進(jìn)行邏輯運(yùn)算,只要它們具有相同的大小表達(dá)式a>=b將會(huì)產(chǎn)生結(jié)果如果這個(gè)數(shù)組具有不同的大小,那么將會(huì)產(chǎn)生運(yùn)行時(shí)錯(cuò)誤。2023年2月4日第32頁運(yùn)算符圓括號(hào)()轉(zhuǎn)置(.’),共軛轉(zhuǎn)置(‘),乘方(.^),矩陣乘方(^)邏輯非(~)乘法(.*),矩陣乘法(*),右除(./),左除(.\),矩陣右除(/),矩陣左除(\)加法(+),減法(-),冒號(hào)運(yùn)算符(:)小于(<),小于等于(<=),大于(>),大于等于(>=),等于(==),不等于(~=)數(shù)組邏輯與(&)數(shù)組邏輯或(|)邏輯與(&&)邏輯或(||)例假設(shè)下面有三個(gè)變量被初始和一些表達(dá)式及其運(yùn)算結(jié)果。value1=1value2=0value3=-102023年2月4日第33頁邏輯表達(dá)式結(jié)果(a)~value10(b)value1|value21(c)value1&value20(d)value1&value2|value31(e)value1&(value2|value3)1(f)~(value1&value3)0因?yàn)閪運(yùn)算在其它的邏輯運(yùn)算之前進(jìn)行,那么(f)中的括號(hào)是必須的。如果去掉括號(hào)的話,(f)表達(dá)式將等價(jià)于(~value1)&value3。4邏輯函數(shù)MATLAB中有大量的邏輯函數(shù),在條件滿足時(shí),函數(shù)返回1。條件不滿足時(shí),返回0。這些邏輯函數(shù)連同關(guān)系運(yùn)算符和邏輯運(yùn)算符一起實(shí)現(xiàn)程序的選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)。2023年2月4日第34頁MATLAB邏輯函數(shù)函數(shù)用途ischar(a)a是字符數(shù)組返回1,否則返回0isempty(a)a是空數(shù)組返回1,否則返回0isinf(a)a是無窮大,則返回1,否則返回0isnan(a)a不是一個(gè)數(shù)則返1,否則返回0isnumeric(a)a是一個(gè)數(shù)值數(shù)組返回1,否則返回0四選擇結(jié)構(gòu)(分支語句)選擇結(jié)構(gòu)可以使MATLAB選擇性執(zhí)行指定區(qū)域內(nèi)的代碼(稱之為語句塊blocks),而跳過其他區(qū)域的代碼。選擇結(jié)構(gòu)在MATLAB中有三種具體的形式:if結(jié)構(gòu),switch結(jié)構(gòu)和try/catch結(jié)構(gòu)。2023年2月4日第35頁1if結(jié)構(gòu)if結(jié)構(gòu)的基本形式如下:其中controlexpression控制if結(jié)構(gòu)的運(yùn)算。如果control_expr_1的值非0,那么程序?qū)?huì)執(zhí)行語句塊1(block1),然后跳到end后面的第一個(gè)可執(zhí)行語句繼續(xù)執(zhí)行。否則,程序?qū)?huì)檢測control_expr_2的值。如果control_expr_2的值非0,那么程序?qū)?huì)執(zhí)行語句塊2(block2),然后跳到end后面的第一個(gè)可執(zhí)行語句繼續(xù)執(zhí)行。如果所有的控制表達(dá)式(controlexpression)均為0,那么程序?qū)?huì)執(zhí)行與else相關(guān)的語句塊。2023年2月4日第36頁在一個(gè)if結(jié)構(gòu)中,可以有任意個(gè)elseif語句,但else語句最多有一個(gè)。只要上面每一個(gè)控制表達(dá)式均為0,那么下一個(gè)控制表達(dá)式將會(huì)被檢測。一旦其中的一個(gè)表達(dá)式的值非0,對應(yīng)的語句塊就要被執(zhí)行,然后跳到end后面的第一個(gè)可執(zhí)行語句繼續(xù)執(zhí)行。如果所有的控制表達(dá)式(controlexpression)均為0,那么程序?qū)?huì)執(zhí)行else語句。如果沒有else語句,程序?qū)?huì)執(zhí)行end后面的語句,而不執(zhí)行if結(jié)構(gòu)中的部分。2023年2月4日第37頁注意MATLAB在if結(jié)構(gòu)中的關(guān)鍵字end與數(shù)組中提到的返回已知下標(biāo)最大值函數(shù)end完全不同。matlab通過end在M文件中的上下文來區(qū)分開它的兩個(gè)用途。在大多數(shù)情況下,控制表達(dá)式均可以聯(lián)合關(guān)系運(yùn)算符和邏輯運(yùn)算符。正像我們在本章早些時(shí)侯學(xué)到的,當(dāng)對應(yīng)的條件為真時(shí),關(guān)系運(yùn)算和邏輯運(yùn)算將會(huì)產(chǎn)生1,否則產(chǎn)生0。所以當(dāng)一個(gè)運(yùn)算條件為真時(shí),運(yùn)算結(jié)果為非0,則對應(yīng)的語句塊,就會(huì)被執(zhí)行。2023年2月4日第38頁例如,一元二次方程的基本形式如下:ax2+bx+c=0

其解為

2023年2月4日第39頁其中b2-4ac是我們熟知的判別式,當(dāng)b2-4ac>0時(shí),方程式有兩個(gè)不同的實(shí)數(shù)根,當(dāng)b2-4ac=0,有兩個(gè)相同的實(shí)數(shù)根,當(dāng)b2-4ac<0時(shí),方程式有兩個(gè)不同的復(fù)根。假設(shè)我們檢測某一元二次根的情況,并告訴使用者這個(gè)方程有兩個(gè)復(fù)根,還是兩個(gè)相等的實(shí)根和兩個(gè)不相等的實(shí)根。用偽代碼這個(gè)結(jié)構(gòu)的形式如下:if(b^2-4*a*c)<0Writemsgthatequationhastwocomplexroots.elseif(b^2-4*a*c)==0Writemsgthatequationhastwoidenticalrealroots.elseWritemsgthatequationhastwodistinctrealroots.end轉(zhuǎn)化為MATLAB語言:if(b^2-4*a*c)<0disp('Thisequationhastwocomplexroots.');elseif(b^2-4*a*c)==0disp('Thisequationhastwoidenticalrealroots.');elsedisp('Thisequationhastwodistinctrealroots.');end2023年2月4日第40頁回憶一下,判斷為真時(shí),關(guān)系運(yùn)算符將會(huì)返回一個(gè)非0值,從而導(dǎo)致對應(yīng)語句的執(zhí)行。為增加程序的可讀性,在if結(jié)構(gòu)中的語句塊中最好縮進(jìn)2到3個(gè)空格,而實(shí)際上沒有必要。你可以在一行內(nèi)寫完一個(gè)完整的if結(jié)構(gòu),只需把結(jié)構(gòu)的每一部分后面加上分號(hào)或逗號(hào),所以下面的兩個(gè)結(jié)構(gòu)是等價(jià)的:ifx<0y=abs(x);end和ifx<0;y=abs(x);end但是這種方式只適用于簡單的結(jié)構(gòu)。2023年2月4日第41頁好的編程習(xí)慣if結(jié)構(gòu)體經(jīng)??s進(jìn)2到3個(gè)空格,以增強(qiáng)程序的可讀性。2if結(jié)構(gòu)舉例我們將本章開頭介紹的方法進(jìn)行編程。1.陳述問題這個(gè)問題的陳述非常的簡單,我們要求一元二次方程的根,不管它的根是實(shí)根還是復(fù)根,有一個(gè)根還是兩個(gè)根。2.定義輸入和輸出本程序的輸入應(yīng)為系數(shù)a,b,cax2+bx+c=0 輸出量應(yīng)為兩個(gè)不相等的實(shí)數(shù)。兩個(gè)相等的實(shí)數(shù)或兩個(gè)復(fù)數(shù)。3.寫出算法本程序可分為三大塊,它的函數(shù)分別為輸入,運(yùn)算過程和輸出。我們把每一個(gè)大塊分解成更小的,更細(xì)微的工作。根據(jù)判別式的值,可能有三種計(jì)算途徑,2023年2月4日第42頁例求一元二次方程的根設(shè)計(jì)并編寫一個(gè)程序,用來求解一元二次方程的根。2023年2月4日第43頁所以我們要用到有三種選項(xiàng)的if結(jié)構(gòu)。產(chǎn)生的偽代碼如下Prompttheuserforthecoefficientsa,b,andc.Reada,b,andcdiscriminant←b^2-4*a*cifdiscriminat>0x1←(-b+sqrt(discriminant))/(2*a)x2←(-b-sqrt(discriminant))/(2*a)Writemsgthatequationhastwodistinctrealroots.Writeoutthetworoots.elseifdiscriminant==0x1←-b/(2*a)Writemsgthatequationhastwoidenticalrealroots.Writeouttherepeatedroots.elsereal_part←-b/(2*a)imag_part←sqrt(abs(discriminant))/(2*a)Writemsgthatequationhastwocomplexroots.Writeoutthetworoots.end4.把算法轉(zhuǎn)化為MATLAB語言5.檢測這個(gè)程序下一步,我們必須輸入實(shí)數(shù)來檢測這個(gè)程序。因這個(gè)程序有三個(gè)可能的路徑。所以在我們確信每一人路徑都工作正常之前,必須把這三個(gè)路徑檢測一遍。從式子中,我們可以有用下面的方法來驗(yàn)證程序的正確性。x2+5x+6=0 x=-2,andx=-=3x2+4x+4=0 x=-2x2+2x+5=0 x=-1±i22023年2月4日第44頁編寫一個(gè)程序,求以x,y為自變量函數(shù)f(x,y)的值。函數(shù)f(x,y)的定義如下:2023年2月4日第45頁根據(jù)自變量x和y的正負(fù)符號(hào)的不同,而采取不同的求值表達(dá)式。為選取合適的表達(dá)式,檢查用戶輸入的x,y的正負(fù)符號(hào)是必要的。1.陳述問題這個(gè)問題的陳述非常簡單:根據(jù)用戶輸入的x,y,求函數(shù)f(x,y)的值。2.確定輸入輸出量程序的輸入量為函數(shù)的自變量x,y。輸出量為函數(shù)值f(x,y)。3.設(shè)計(jì)算法這個(gè)問題可以把他分解成三個(gè)大塊,即輸入,計(jì)算過程,和輸出。我們把這三大塊再分解成小的,精細(xì)的工作。在計(jì)算f(x,y)時(shí),我們有4種選擇,選哪一種取決于x,y的值。所以邏輯上我們要用4個(gè)選擇的if結(jié)構(gòu)來實(shí)現(xiàn)。產(chǎn)生的偽代碼如下:PrompttheuserforthevaluesxandyReadxandyifx≥0andy≥0fun←x+yelseifx≥0andy<0fun←x+y^2elseifx<0andy≥0fun←x^2+yelsefun←x^2+y^2endWriteoutf(x,y)2023年2月4日第46頁5.檢測程序下一步,我們必須輸入實(shí)數(shù)來檢測這個(gè)程序。因這個(gè)程序有四個(gè)可能的路徑。所以在我們確信每一人路徑都工作正常之前,必須把這四個(gè)路徑檢測一遍。我們分別取4個(gè)象限內(nèi)的值(2,3),(-2,-3),(-2,3)和(--2,--3)。我們用手工計(jì)算可得f(2,3)=2+3=5f(2,-3)=2+(-3)2=11f(-2,3)=(-2)2+3=7f(-2,-3)=(-2)2+(-3)2=132023年2月4日第47頁3關(guān)于if結(jié)構(gòu)使用的注意事項(xiàng)if結(jié)構(gòu)是非常靈活的,它必須含有一個(gè)if語句和一個(gè)end語句。中間可以有任意個(gè)elseif語句,也可以有一個(gè)else語句。聯(lián)合它的這些特性,我們可以創(chuàng)建出我們需要的各種各樣的選擇結(jié)構(gòu)。還有if語句是可以嵌套的。如果if結(jié)構(gòu)完全是另一個(gè)if結(jié)構(gòu)的一個(gè)語句塊,我們就稱兩者為嵌套關(guān)系。下面是兩個(gè)if語句的嵌套。ifx>0...ify<0...end...end2023年2月4日第48頁MATLAB翻譯器經(jīng)常把把已知的end語句和它最近的if語句聯(lián)合在一起,所以第一個(gè)end語句和ify<0最靠近,而第二個(gè)end與ifx>0最接近。對于一個(gè)編寫正確的程序,它能工作正常。但如果程序員編寫出錯(cuò)誤,它將會(huì)使編譯器出現(xiàn)混淆性錯(cuò)誤信息提示。例如,假設(shè)我們編寫一個(gè)大的程序,包括如下的一個(gè)結(jié)構(gòu):...if(test1)...if(test2)...if(test3)...end...end...end2023年2月4日第49頁這個(gè)程序包括了三個(gè)嵌套的if結(jié)構(gòu),在這個(gè)結(jié)構(gòu)中可能有上千行的代碼。現(xiàn)在假設(shè)第一個(gè)end在編輯區(qū)域突然被刪除,那么MATLAB編譯器將會(huì)自動(dòng)將第二個(gè)end與最里面的if(test3)結(jié)構(gòu)聯(lián)合起來,第三個(gè)end將會(huì)和中間的if(test2)聯(lián)合起來。當(dāng)編譯器翻譯到達(dá)文件結(jié)束的時(shí)候,那將發(fā)現(xiàn)第一個(gè)if(test1)結(jié)構(gòu)將永遠(yuǎn)沒有結(jié)束,然后編譯器就會(huì)產(chǎn)生一個(gè)錯(cuò)誤提示信息,即缺少一個(gè)end。但是,它不能告訴你問題發(fā)生在什么地方,這就使我們必須回過頭去看整個(gè)程序,來找問題。在大多數(shù)情況下,執(zhí)行一個(gè)算法,即可以用多個(gè)elseif語句,也可以用if語句的嵌套。在這種情況下,大家可以選擇自己喜歡的方式。例給出等級(jí)分?jǐn)?shù)假設(shè)我們要編寫一個(gè)程序,輸入一個(gè)數(shù)值分?jǐn)?shù),輸出等級(jí)分?jǐn)?shù),即是A級(jí),B級(jí)和C級(jí)

grade>95 A95≥grade>86 B86≥grade>76 C76≥grade>66 D66≥grade>0 F用兩種方式寫出這個(gè)程序,第一種方式用多個(gè)elseif語句,第二種方式用if的嵌套。2023年2月4日第50頁(a)用多個(gè)elseif語句ifgrade>95.0disp('ThegradeisA.');elseifgrade>86.0disp('ThegradeisB.');elseifgrade>76.0disp('ThegradeisC.');elseifgrade>66.0disp('ThegradeisD.');elsedisp('ThegradeisF.');end2023年2月4日第51頁(b)用if嵌套結(jié)構(gòu)ifgrade>95.0disp('ThegradeisA.');elseifgrade>86.0disp('ThegradeisB.');elseifgrade>76.0disp('ThegradeisC.');elseifgrade>66.0disp('ThegradeisD.');elsedisp('ThegradeisF.');endendendend2023年2月4日第52頁從上面的例子中,我們可以看到如果有多個(gè)選項(xiàng)的話,在一個(gè)if結(jié)構(gòu)中用到多個(gè)elseif語句將會(huì)比if的嵌套結(jié)構(gòu)簡單的多。2023年2月4日第53頁好的編程習(xí)慣對于有許多選項(xiàng)的選擇結(jié)構(gòu)來說,最好在一個(gè)if結(jié)構(gòu)中使用多個(gè)elseif語句,盡量不用if的嵌套結(jié)構(gòu)。4switch結(jié)構(gòu)switch結(jié)構(gòu)是另一種形式的選擇結(jié)構(gòu)。程序員可以根據(jù)一個(gè)單精度整形數(shù),字符或邏輯表達(dá)式的值來選擇執(zhí)行特定的代碼語句塊。2023年2月4日第54頁如果switch_expr的值與case_expr_1相符,那么第一個(gè)代碼塊將會(huì)被執(zhí)行,然后程序?qū)?huì)跳到switch結(jié)構(gòu)后的第一個(gè)語句。如果switch_expr的值與case_expr_2相符,那么第二個(gè)代碼塊將會(huì)被執(zhí)行,然后程序?qū)?huì)跳到switch結(jié)構(gòu)后的第一個(gè)語句。在這個(gè)結(jié)構(gòu)中,用相同的方法來對待其他的情況。otherwise語句塊是可選的。如果它存在的話,當(dāng)switch_expr的值與其他所有的選項(xiàng)都不相符時(shí),這個(gè)語句塊將會(huì)被執(zhí)行。如果它不存在,且witch_expr的值與其他所有的選項(xiàng)都不相符,那么這個(gè)結(jié)構(gòu)中的任何一個(gè)語句塊都不會(huì)被執(zhí)行。這種情況下的結(jié)果可以看作沒有選擇結(jié)構(gòu),直接執(zhí)行MATLAB語言。如果說switch_expr有很多值可以導(dǎo)致相同代碼的執(zhí)行,那么這些值可以括在同一括號(hào)內(nèi),如下所示。如果這個(gè)switch表達(dá)式和表中任何一個(gè)表達(dá)式相匹配,那么這個(gè)語句塊將會(huì)被執(zhí)行。2023年2月4日第55頁switch_expr和每一個(gè)case_expr既可以是數(shù)值,也可以是字符值。注意在大多情況下只有一個(gè)語句塊會(huì)被執(zhí)行。當(dāng)一個(gè)語句塊被執(zhí)行后,編譯器就會(huì)跳到end語句后的第一個(gè)語句開始執(zhí)行。如果switch表達(dá)和多個(gè)case表達(dá)式相對應(yīng),那么只有他們中的第一個(gè)將會(huì)被執(zhí)行。讓我們看一個(gè)簡單的關(guān)于switch結(jié)構(gòu)的例子。下面的語句用來判斷1到10之間的數(shù)是奇數(shù)還是偶數(shù)。它用來說明一系列的case選項(xiàng)值的應(yīng)用和otherwise語塊的應(yīng)用。switch(value)case{1,3,5,7,9},disp('Thevalueisodd.');case{2,4,6,8,10},disp('Thevalueiseven.');otherwise,disp('Thevalueisoutofrange.');end2023年2月4日第56頁5try/catch結(jié)構(gòu)的應(yīng)用try/catch結(jié)構(gòu)是選擇結(jié)構(gòu)的一種特殊形式,用于捕捉錯(cuò)誤。一般地,當(dāng)一個(gè)MATLAB程序在運(yùn)行時(shí)遇到了一個(gè)錯(cuò)誤,這個(gè)程序就會(huì)中止執(zhí)行。try/catch結(jié)構(gòu)修改了這個(gè)默認(rèn)行為。如果一個(gè)錯(cuò)誤發(fā)生在這個(gè)結(jié)構(gòu)的try語句塊中,那么程序?qū)?huì)執(zhí)行catch語句塊,程序?qū)⒉粫?huì)中斷。它將幫助程序員控制程序中的錯(cuò)誤,而不用使程序中斷。2023年2月4日第57頁Try/catch結(jié)構(gòu)的基本形式如下:2023年2月4日第58頁當(dāng)程序運(yùn)行到try/catch語句塊,在try語句塊中的一些語句將會(huì)被執(zhí)行。如果沒有錯(cuò)誤出現(xiàn),catch語句塊將會(huì)被跳過。另一方面,如果錯(cuò)誤發(fā)生在一個(gè)try語句塊,那么程序?qū)⒅兄箞?zhí)行try語句塊,并立即執(zhí)行catch語句塊。下面有一個(gè)包含try/catch結(jié)構(gòu)程序。它能創(chuàng)建一個(gè)數(shù)組,并詢問用戶顯示數(shù)組中的哪一個(gè)元素。用戶提供一個(gè)下標(biāo),那么這個(gè)程序?qū)?huì)顯示對應(yīng)的數(shù)組元素,try語句塊一般會(huì)在這個(gè)程序中執(zhí)行,只有當(dāng)try語句塊執(zhí)行出錯(cuò),catch語句塊將會(huì)發(fā)生錯(cuò)誤。2023年2月4日第59頁%Initializearraya=[1-325];try%Trytodisplayanelementindex=input('Entersubscriptofelementtodisplay:');disp(['a('int2str(index)')='num2str(a(index))]);catch%Ifwegethereanerroroccurreddisp(['Illegalsubscript:'int2str(index)]);end這個(gè)程序的執(zhí)行結(jié)果如下:>>try_catchEntersubscriptofelementtodisplay:3a(3)=2>>try_catchEntersubscriptofelementtodisplay:8Illegalsubscript:82023年2月4日第60頁五

程序調(diào)試的進(jìn)一步說明在含有選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)的程序出錯(cuò)的概率要比只含簡單的順序結(jié)構(gòu)的程序出錯(cuò)的概率大得多。在完成了程序設(shè)計(jì)的步驟之后,無論多大的一個(gè)程序,在第一次運(yùn)行時(shí)都很難通過。假如我們創(chuàng)建了一個(gè)程序并調(diào)試它,只發(fā)現(xiàn)這個(gè)程序的輸出是錯(cuò)誤的。我們怎樣找到這些錯(cuò)誤并修改它呢?一旦程序包含了循環(huán)和選擇結(jié)構(gòu),找到錯(cuò)語的最好的方法是應(yīng)用matlab支持的符號(hào)調(diào)試器(symbolicdeb

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(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ǔ)空間,僅對用戶上傳內(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論