版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
第三章M文件初步前面的章節(jié)介紹了如何在MATLAB操作桌面完成運算,適合于指令條數(shù)不太多的情況。如果用戶需要用到多條指令或者需要經(jīng)常這些指令,則采用編寫程序的方式完成起來會更方便。MATLAB為用戶專門提供了M文件,可以讓用戶自行將指令寫成程序,存儲為文件后運行完成相應(yīng)的工作。M文件簡介M文件分為腳本文件(ScriptFile,標(biāo)識為)和函數(shù)文件(FunctionFile,標(biāo)識為)兩種形式,它們的擴展名都是.m。腳本文件的效果等同于將指令逐條輸入指令窗執(zhí)行,因此,腳本文件在執(zhí)行時,用戶可以查看或者調(diào)用工作空間中的變量。函數(shù)文件則需要通過輸入宗量和輸出宗量來傳遞信息,如果沒有特別設(shè)置,函數(shù)文件猶如一個暗箱,函數(shù)文件中的中間變量在工作空間是看不見的,并隨著函數(shù)文件執(zhí)行結(jié)束而擦除。MATLAB強大的科學(xué)技術(shù)資源來自于MATLAB內(nèi)部儲存了豐富的函數(shù)文件,日益豐富的函數(shù)文件資源也是MATLAB版本升級的基礎(chǔ)。 本章主要內(nèi)容包括:M文件的分類及其編寫入門MATLAB中不同流程控制語句及其使用技巧不同類型函數(shù)文件的創(chuàng)建及其調(diào)試本章將系統(tǒng)介紹M文件的種類、函數(shù)文件的構(gòu)造,以及MATLAB程序的跟蹤調(diào)試。M文件簡介3.1M文件入門M文件是個文本文件,可以用任何編輯程序來建立和編輯,一般最常用且最方便的是使用MATLAB提供的文件編輯器(MATLABEditor/Debugger)。缺省情況下,M文件編輯器不隨MATLAB的啟動而開啟,只有編寫M文件才能啟動。為建立新的M文件,啟動MATLAB文件編輯器有3種方法3.1.1M文件的建立(1)命令按鈕操作鼠標(biāo)左鍵單擊MATLAB主窗口工具欄上的NewScript命令按鈕,則會出現(xiàn)標(biāo)準(zhǔn)的MATLAB函數(shù)文件編輯窗口(2)菜單操作從MATLAB主窗口中選擇File→New→Script,出現(xiàn)MATLAB腳本文件編輯窗口;如果希望新建函數(shù)文件,則選擇File→New→Function,則出現(xiàn)標(biāo)準(zhǔn)的MATLAB函數(shù)文件編輯調(diào)試窗口。(3)命令操作:在MATLAB命令窗口執(zhí)行指令edit,MATLAB將啟動新建圖3.1的腳本文件編輯窗口。3.1.2M文件編寫初步本節(jié)將通過編寫腳本文件和函數(shù)文件執(zhí)行相同的運算。通過這兩個文件,用戶可以初步了解腳本文件和函數(shù)文件。對于其中涉及的語言結(jié)構(gòu),文章后面將有詳細介紹。【例3-1】編寫一個腳本文件,計算編寫腳本文件的步驟:(1)啟動M文件編輯調(diào)試器,建立新的腳本文件。(2)編寫程序并保存在腳本文件空白處輸入指令:%腳本文件示例clearn=20;sum=0;fork=1:nsum=sum+k;endsum指令輸入完畢后保存該文件:單擊M文件編輯調(diào)試器工具條上的保存圖標(biāo),便出現(xiàn)標(biāo)準(zhǔn)的文件保存對話框。在文件保存對話框中選定目錄,鍵入程序的文件名(如exm3_1),單擊保存即可;或者從M文件編輯調(diào)試器窗口中選擇File→Save或者SaveAs也可以保存。保存完畢后原來的未命名(Untitled)M文件立即顯示輸入的文件名和路徑?!纠?-1】編寫一個腳本文件,計算(3)運行腳本文件設(shè)置腳本文件exm3_1.m所在目錄為當(dāng)前目錄,或者讓該目錄處于MATLAB的檢索路徑上,在指令窗中輸入文件名exm3_1并運行。>>exm3_1sum=210【說明】:運行M文件的操作方法有很多,最常用的方法有:(1)在指令窗中運行M文件,M文件不帶擴展名。(2)在當(dāng)前目錄窗中,用鼠標(biāo)右鍵單擊待運行文件,再從引出的現(xiàn)場菜單中選擇【Run】即可。在M文件編輯器中,注釋部分可以采用漢字,并總可以獲得準(zhǔn)確顯示。當(dāng)使用M文件便器調(diào)試器保存文件時,不必寫出文件的擴展名?!纠?-1】編寫一個腳本文件,計算【例3-2】運用M函數(shù)文件編寫例3-1中的求和計算,要求n為任意自然數(shù)。編寫函數(shù)文件的步驟:(1)啟動M函數(shù)文件編輯調(diào)試器,建立新的函數(shù)文件。(2)編寫程序并保存將輸入宗量(inputargs)、輸出宗量(outputargs)和函數(shù)名等處做相應(yīng)修改保存該函數(shù)文件,文件名為exm3_2。(2)運行函數(shù)文件在MATLAB指令窗中輸入指令并運行:>>sum=exm3_2(20)sum=210所得結(jié)果與上題相同?!纠?-2】運用M函數(shù)文件編寫例3-1中的求和計算,要求n為任意自然數(shù)。說明:在指令窗中執(zhí)行函數(shù)文件時必須事前在工作空間中產(chǎn)生輸入宗量的值,或者直接將輸入宗量的值鍵入函數(shù)名后面的小括號中。用戶如果像執(zhí)行腳本文件一樣執(zhí)行函數(shù)文件,即僅鍵入exm3_2,則MATLAB將提示出錯。函數(shù)文件在保存時,MATLAB將函數(shù)名默認(rèn)為文件名,建議用戶不要隨意修改。一旦函數(shù)文件的文件名和函數(shù)名不一致時,MATLAB將以函數(shù)文件的文件名為準(zhǔn)來執(zhí)行。用戶可以通過在腳本文件中使用交互式輸入指令input(),達到和函數(shù)文件相似的執(zhí)行效果。建議用戶將腳本文件exm3_1中的語句"n=20"修改為"n=input('n=?');",重新運行后觀察其執(zhí)行情況。3.2MATLAB流程控制結(jié)構(gòu)MATLAB為用戶提供了4種流程控制結(jié)構(gòu):條件結(jié)構(gòu)、循環(huán)結(jié)構(gòu)、開關(guān)結(jié)構(gòu)和試探結(jié)構(gòu)。用戶可以根據(jù)某些判斷結(jié)果來控制程序流的執(zhí)行次序。與其他程序語言相比,除了試探結(jié)構(gòu)為MATLAB所特有外,其他結(jié)構(gòu)和用法都十分相似,因此本節(jié)只結(jié)合MATLAB特點對這幾種流程控制結(jié)構(gòu)做簡要說明。3.2.1if條件結(jié)構(gòu)If條件結(jié)構(gòu)是實現(xiàn)分支結(jié)構(gòu)程序的最常用的一種語句,能夠?qū)崿F(xiàn)單分支、雙分支和多分支結(jié)構(gòu)。
單分支結(jié)構(gòu)的形式:if邏輯表達式
指令語句組
end雙分支結(jié)構(gòu)的形式:if邏輯表達式指令語句組1else
指令語句組2end多分支結(jié)構(gòu)的形式:if邏輯表達式1
指令語句組1elseif邏輯表達式2
指令語句組2
……elseif邏輯表達式n
指令語句組nelse
指令語句組n+1end3.2.1if條件結(jié)構(gòu)【說明】:在單分支結(jié)構(gòu)中,當(dāng)邏輯表達式為“邏輯真”(非0)時,則執(zhí)行相應(yīng)的指令語句組,否則,則跳過該指令組。對于雙分支結(jié)構(gòu),當(dāng)邏輯表達式為“邏輯真”時,則執(zhí)行指令語句組1,否則,執(zhí)行指令語句組2;多分支結(jié)構(gòu)中,MATLAB將依次判斷邏輯表達式是否為“邏輯真”,當(dāng)前面所有的邏輯表達式都為“邏輯假”(0)時,MATLAB執(zhí)行指令語句組n+1,并結(jié)束該結(jié)構(gòu)。3.2.1if條件結(jié)構(gòu)邏輯表達式的形式大致有兩種:一種是以標(biāo)量或者數(shù)組形式;另一種是由多個邏輯表達式進行關(guān)系運算的形式。當(dāng)形式為數(shù)組時,只有當(dāng)數(shù)組中的所有元素都為“邏輯真”時,MATLAB才會執(zhí)行對應(yīng)條件的語句。后者的關(guān)系運算主要為“與(&)”“或(|)”運算。【例3-3】求分段函數(shù)的值。編寫文件名為exm3_3的腳本文件:clearx=input('請輸入x=?');ifx>=0&x<=1y=2*sqrt(x)elseifx>1y=1+x+log(x)elsedisp('Nodefination')end在指令窗中執(zhí)行文件exm3_3.m,運行結(jié)果為:請輸入x=?用戶將需要計算的數(shù)值送給MATLAB,這里以x=6為例:請輸入x=?6y=
8.7918【例3-3】求分段函數(shù)的值。MATLAB從5.0版本開始,提供了switch-case開關(guān)結(jié)構(gòu),調(diào)用格式為:
switch開關(guān)表達式
case表達式1指令語句組1
case表達式2指令語句組2
……
case表達式n指令語句組n
otherwise指令語句組n+1
end3.2.1switch-case開關(guān)結(jié)構(gòu)【說明】:<1>開關(guān)結(jié)構(gòu)在運行時,MATLAB將開關(guān)表達式的值依次和各個case后面的表達式進行比較,如果是“邏輯真”,將執(zhí)行相應(yīng)的指令語句,如果是“邏輯假”,則取下一個case后面的表達式比較。如果所有case后面表達式都與開關(guān)表達式的值不相等,則執(zhí)行otherwise后面的指令語句組。<2>開關(guān)表達式形式有兩種:一種是標(biāo)量;另外一種為字符串。對于字符串形式,MATLAB在比較時將調(diào)用函數(shù)strcmp(),得出字符串比較的邏輯輸出值,MATLAB根據(jù)該邏輯值的真假來判斷是否執(zhí)行該case后面的語句?!纠?-4】switch-case開關(guān)結(jié)構(gòu)實例:通過鍵盤輸入百分制成績,輸出成績的等級,其中90~100分等級為A,80~89分等級為B,70~79分等級為C,60~69分等級為D,60分以下等級為E。編寫文件名為exm3_4的腳本文件:n=input('請輸入百分制成績n=?');ifn<0|n>100disp('輸入有誤,請重新輸入百分制成績')elset=fix(n/10);%fix()為截斷取整函數(shù)switchtcase{9,10}disp('A')case8disp('B')case7disp('C')case6disp('D')otherwisedisp('E')endend【例3-4】switch-case開關(guān)結(jié)構(gòu)實例:在指令窗中執(zhí)行文件exm3_4.m,并以n=86分為例,運行結(jié)果為:請輸入百分制成績n=?86B【例3-4】switch-case開關(guān)結(jié)構(gòu)實例:【例3-5】求分段函數(shù)的值編寫文件名為exm3_5的腳本文件:clearx=input('請輸入x的值:');switch1casex<=1&x~=-3y=sqrt(1+x^2)/log(3)casex>2y=(x+log10(7))/exp(1)otherwisey=x/piend注意:程序中switch后面的1為邏輯1,表示條件永真。該題為三分支結(jié)構(gòu)問題,可以用if條件結(jié)構(gòu)來編寫。方法一:利用switch-case開關(guān)結(jié)構(gòu):方法二:利用if條件結(jié)構(gòu)clearx=input('請輸入x的值:');ifx<=1&x~=-3y=sqrt(1+x^2)/log(3)elseifx>2y=(x+log10(7))/exp(1)elsey=x/piend3.2.3try試探結(jié)構(gòu)MATLAB從5.2版本開始添加了這一新的結(jié)構(gòu),其一般格式如下:
try指令語句組1
catch指令語句組2
end【說明】:試探結(jié)構(gòu)首先試探性地執(zhí)行指令語句組1,如果在此語句組執(zhí)行過程中出現(xiàn)錯誤,則將錯誤信息賦給保留的lasterr變量,并放棄這組語句,轉(zhuǎn)而執(zhí)行語句組2中的語句。若語句組2執(zhí)行過程中又出現(xiàn)錯誤,MATLAB將終止該結(jié)構(gòu)?!纠?-6】對3階魔方陣的行進行引用,當(dāng)行下標(biāo)超出魔方陣的最大行數(shù)時改為對最后一行的引用,并顯示出錯警告信息。3.2.3try試探結(jié)構(gòu)編寫文件名為exm3_6的腳本文件:N=input('提取魔方陣的第N行元素,其中N=?');A=magic(3);%執(zhí)行函數(shù)magic()產(chǎn)生3×3魔方矩陣tryA_N=A(N,:)%取A的第N行catchA_end=A(end,:)%取A的最后一行end3.2.3try試探結(jié)構(gòu)在指令窗中執(zhí)行文件exm3_6.m,并以N=6為例,運行結(jié)果為:取魔法陣的第N行,其中N=?6A_end=492ans=AttemptedtoaccessA(6,:);indexoutofboundsbecausesize(A)=[3,3].3.2.4for循環(huán)結(jié)構(gòu)for語句是一種基本的實現(xiàn)循環(huán)結(jié)構(gòu)的語句,能夠以確定的次數(shù)執(zhí)行某一段程序。for語句的格式如下:
for循環(huán)變量=表達式循環(huán)體指令語句組
end【說明】“表達式”可以是MATLAB指令產(chǎn)生的數(shù)組,也可以是任意給定的一個數(shù)組。循環(huán)變量從“表達式”中的第一個數(shù)值(或第一列數(shù)組)一直循環(huán)到“表達式”的最后一個數(shù)值(或最后一列數(shù)組)?!纠?-7】運用for…end循環(huán)結(jié)構(gòu)計算的值,(其中m=100)運用for…end循環(huán)結(jié)構(gòu)計算,編寫文件名為exm3_7的腳本文件:cleary=0;forn=0:100y=y+1/(2^n+1);endY在指令窗中執(zhí)行文件exm3_7.m,運行結(jié)果為:y=1.2645a=0+eps;%利用極小數(shù)代替0,避免計算時出錯b=3;n=1000;h=(b-a)/n;x=a:h:b;y=0;f=log(x)./(2*x.^2+1);fori=1:ns(i)=(f(i)+f(i+1))*h/2;%計算細分后梯形的面積
y=y+s(i);%迭代法endy【例3-8】運用循環(huán)結(jié)構(gòu)計算積分在指令窗中執(zhí)行該文件,運行結(jié)果為:y=-0.7730【例3-8】一個三位整數(shù)各位數(shù)字的立方和等于該數(shù)本身,則稱該數(shù)為水仙花數(shù)。運用for…end循環(huán)結(jié)構(gòu)輸出全部水仙花數(shù)。clearform=[100:999]m1=fix(m/100);%求m的百位數(shù)字,函數(shù)fix()功能為截斷取整
m2=rem(fix(m/10),10);%求m的十位數(shù)字,rem()為求余函數(shù)
m3=rem(m,10);%求m的個位數(shù)字
ifm==m1*m1*m1+m2*m2*m2+m3*m3*m3disp(m)endend運行結(jié)果為:
1533703714073.2.5while循環(huán)結(jié)構(gòu)
while結(jié)構(gòu)是MATLAB語言實現(xiàn)循環(huán)結(jié)構(gòu)的另一種基本方式,以不定的次數(shù)重復(fù)執(zhí)行某一段程序。
while循環(huán)結(jié)構(gòu)的一般形式如下:
while邏輯表達式指令語句組
end執(zhí)行時,只要邏輯表達式為“邏輯真”(非0),就執(zhí)行指令語句組,執(zhí)行后再返回到while引導(dǎo)的邏輯表達式處,繼續(xù)判斷;如果邏輯表達式為“邏輯假”(0),則跳出循環(huán)。通常,邏輯表達式的值為一個標(biāo)量,但數(shù)組也同樣有效。如果邏輯表達式的值為數(shù)組,要求數(shù)組的所有元素都為“邏輯真”(非0),MATLAB才會執(zhí)行循環(huán)體中的指令語句組。如果邏輯表達式為“空”,MATLAB則認(rèn)為表達式的值為邏輯假,不執(zhí)行循環(huán)體語句指令組。clearval=input('Enteranumber(endin0):');sum=0;cnt=0;while(val~=0)sum=sum+val;cnt=cnt+1;val=input('Enteranumber(endin0):');endif(cnt>0)summean=sum/cntend用戶可以在指令窗中執(zhí)行該文件,將數(shù)字逐個輸入并獲得運行結(jié)果?!纠?-9】運用while…end循環(huán)結(jié)構(gòu)實例:從鍵盤輸入若干個數(shù),當(dāng)輸入為0時結(jié)束輸入。求這些數(shù)的平均值和它們的和。與循環(huán)語句有關(guān)的語句還有break和continue語句,它們一般和if語句配合使用。break語句用于終止循環(huán)的執(zhí)行,當(dāng)在循環(huán)體內(nèi)執(zhí)行到該語句時,程序?qū)⑻鲈撗h(huán);continue語句控制跳過循環(huán)體內(nèi)的某些語句,當(dāng)在循環(huán)體內(nèi)執(zhí)行到該語句時,程序?qū)⑻^本次循環(huán),繼續(xù)下一次循環(huán)。【例3-10】求[200,300]間第一個能被18整除的整數(shù)。
編寫文件名為exm3_10的腳本文件:clearforn=200:300ifrem(n,18)~=0continueendbreakendn在指令窗中執(zhí)行文件exm3_10.m,運行結(jié)果為:
n=
2163.2.6控制程序流的其他常用指令MATLAB中有幾個指令能夠使用戶所編輯的程序具有交互性,使用這些指令有助于用戶對程序做調(diào)試。1.input()和keyboard(1)input()指令input()指令常用格式為:v=input('message')v=input('message','s')input()指令將MATLAB的“控制權(quán)”暫時交給用戶。當(dāng)用戶通過鍵盤從指令窗中輸入數(shù)據(jù)并執(zhí)行后,所輸入的內(nèi)容被保存在變量v中,同時“控制權(quán)”被交還給MATLAB。message為顯示在指令窗中的字符串,用戶在指令窗中通過該提示給變量v賦值。第一種格式中,用戶可以輸入數(shù)值、字符串、元胞等各種形式的數(shù)據(jù)形式,變量v保持原來數(shù)據(jù)形式不變;第二種格式中無論用戶輸入什么類型的數(shù)據(jù)形式,變量v總是被看做是字符串。(2)keyboard指令當(dāng)程序遇到該指令時,MATLAB將“控制權(quán)”交給用戶,用戶從鍵盤上輸入各種MATLAB指令。當(dāng)用戶執(zhí)行指令return時,“控制權(quán)”交還給MATLAB。2.disp()指令和echo指令disp()指令的常用格式為:disp(a):顯示變量a的結(jié)果,無須在指令窗中顯示字符a。echo指令控制函數(shù)文件程序是否需要在屏幕上顯示:當(dāng)MATLAB執(zhí)行程序中遇到echoon指令時,會顯示當(dāng)前執(zhí)行的程序內(nèi)容;echooff為解除echoon指令。3.pause指令pause指令的格式為:pause:暫停執(zhí)行程序,等待用戶按任意鍵繼續(xù)執(zhí)行程序。pause(n):暫停n秒后,繼續(xù)執(zhí)行程序。3.2.6控制程序流的其他常用指令4.警示指令當(dāng)程序執(zhí)行中出現(xiàn)錯誤時,利用警示指令可以了解出錯情況。常用的警示指令有:lasterr:顯示MATLAB自動判斷的最新出錯原因,終止運行程序。lastwarn:顯示MATLAB自動判斷的最新出錯原因,繼續(xù)運行程序。warning('message'):顯示警告信息message,繼續(xù)運行程序。error('message'):顯示警告信息message,終止運行程序。errortrap:出錯后,是否繼續(xù)運行程序的切換開關(guān)。3.2.6控制程序流的其他常用指令3.2.7加快MATLAB程序運行速度的技巧由于MATLAB語言為解釋性語言,因此,較其他語言來說,MATLAB語言運行速度不太理想,因此,提高MATLAB程序運行效率就顯得尤為重要。本文通過一個例題給用戶一個具體的體會?!纠?-11】提高MATLAB代碼運行效率實例:采用不同編程方法計算1‐100000的平方根,比較運行時間。編寫文件名為exm3_11的腳本文件:
clear
nm=100000;
%循環(huán)變量為標(biāo)量時,顯示運行時間
tic%打開定時器
forn=1:nm%循環(huán)變量為標(biāo)量
a(n)=sqrt(n);
endt1=toc%顯示定時器的時間
%循環(huán)變量為向量時,顯示運行時間
clearain
tic;
in=[1:nm];
forn=in%循環(huán)變量為向量
a(n)=sqrt(n);
end
t2=toc3.2.7加快MATLAB程序運行速度的技巧
%向量化編程代替循環(huán)結(jié)構(gòu)后的運行時間
clearain
tic;in=[1:nm];
a=sqrt(in);
t4=toc
%向量化編程代替循環(huán)結(jié)構(gòu),且對輸出變量a進行預(yù)定義后的運行時間
clearain
tic
in=[1:nm];
a=zeros(1,nm);
a=sqrt(in);
t5=toc3.2.7加快MATLAB程序運行速度的技巧在指令窗中執(zhí)行文件exm3_9.m,運行結(jié)果為:
t1=
75.9691
t2=
76.7798
t3=
0.2133
t4=
0.0273
t5=
0.04073.2.7加快MATLAB程序運行速度的技巧【說明】在循環(huán)結(jié)構(gòu)中,對輸出變量進行預(yù)定義可以大大縮短程序運行的時間,因此,為了提高MATLAB的執(zhí)行效率,在循環(huán)語句之前盡量對向量或者矩陣進行預(yù)定義。但對于向量化編程,這種情況往往不見效。在實際的MATLAB編程中,采用循環(huán)語句會降低程序的執(zhí)行速度。為了得到高效代碼,應(yīng)盡量提高代碼的向量化程度,即運用“向量化編程”,避免使用循環(huán)結(jié)構(gòu)。合理安排多重循環(huán)的次序,盡量較少外循環(huán)的次序,可以顯著提高程序的運行速度。在不同的計算機上運算時間可能各不相同,但其快慢的次序不變。3.3腳本文件和函數(shù)文件對于較為簡單的問題,從指令窗中直接輸入指令進行計算是非常簡單的事情,但當(dāng)完成一個計算需要許多條指令,或者需要對相同指令進行多次重復(fù)操作時,直接從指令窗中輸入指令已經(jīng)不太合適,此時,采用腳本文件是最佳選擇。腳本文件是由MATLAB支持的指令組成。執(zhí)行時只需要在指令窗中輸入文件名并運行,或者單擊MATLAB操作桌面工具條上的圖標(biāo),打開該腳本文件,鼠標(biāo)右擊引出現(xiàn)場菜單。選中菜單【run】即可;再者可以在打開的腳本文件工具條中點擊圖標(biāo)運行。腳本文件的功能非常強大。它允許用戶自由編寫復(fù)雜的程序,仔細檢查和修改。不會因為用戶的一個無意操作而導(dǎo)致MATLAB盲目執(zhí)行。腳本文件允許用戶調(diào)用各種已經(jīng)存在的函數(shù)文件,是一個非常有用的工具。3.3.1腳本文件腳本文件的構(gòu)成比較簡單,其特點為:它只是一串按照用戶意圖排列而成的MATLAB指令集合。腳本文件只對MATLAB工作空間中的變量進行處理,并且文件中所有指令執(zhí)行結(jié)果也都駐留在MATLAB基本工作空間(BaseWorkspace)中。只要用戶不使用指令cleas加以清除,且MATLAB指令窗不關(guān)閉,則產(chǎn)生的變量將一直保存在基本工作空間中,供用戶查看或者與其他腳本文件共享。3.3.1腳本文件3.3.2函數(shù)文件函數(shù)文件是MATLAB工作的基石,MATLAB的科學(xué)技術(shù)資源來自于MATLAB后臺諸多的函數(shù)文件,MATLAB不斷升級的版本其功能的擴展也正基于添加更多更新功能的函數(shù)文件。1函數(shù)文件的特點與腳本文件相同,函數(shù)文件也是以擴展名".m"作為后綴。因此,從文件的名稱上是不能區(qū)分腳本文件和函數(shù)文件。但與腳本文件相比,函數(shù)文件更像是一個“暗箱”。從外部只能看到傳輸給它的輸入變量和送出來的輸出變量,其內(nèi)部運行是不可見的。函數(shù)文件的第一個可執(zhí)行指令總是以"function"引導(dǎo)的“函數(shù)說明行(FunctionDeclarationLine)”。該行還列出函數(shù)的輸入變量(input_args)和輸出變量(output_args)。有時函數(shù)的輸入變量可能不只是一個或者沒有。輸出變量也可能是不只是一個或者沒有。與腳本文件不同,函數(shù)文件在運行時,MATLAB會為它開辟一個臨時工作空間(ContextWorkspace),稱為函數(shù)工作空間(FunctionWorkspace),函數(shù)文件中除了輸入輸出宗量外的中間變量都存放在函數(shù)工作空間中。當(dāng)函數(shù)文件的最后一條指令執(zhí)行完畢,或者遇到return指令時,函數(shù)工作空間及其所有的中間變量被立即刪除。函數(shù)工作空間相對于基本工作空間來說是獨立的,它隨函數(shù)文件的被調(diào)用而產(chǎn)生,隨函數(shù)調(diào)用的結(jié)束而刪除。在MATLAB整個運行期間可以產(chǎn)生任意多個函數(shù)工作空間。函數(shù)文件執(zhí)行中發(fā)生對某個腳本文件的調(diào)用,那么該腳本文件運行產(chǎn)生的所有變量都存放在函數(shù)臨時工作空間中,而不是存放在基本工作空間。1函數(shù)文件的特點2函數(shù)文件的結(jié)構(gòu)典型的函數(shù)文件格式如下:
Function[輸出變量]=函數(shù)名(輸入變量)函數(shù)注釋行函數(shù)體語句【例3-12】編寫函數(shù)文件產(chǎn)生擴展希爾伯特矩陣,要求:(1)檢測輸入輸出宗量的個數(shù),如果有錯誤,則給出相關(guān)信息。(2)如果用戶只提供一個輸入宗量,則產(chǎn)生希爾伯特方陣。如果用戶沒有要求輸出宗量,則顯示產(chǎn)生矩陣的結(jié)果。(3)文件中給出合適的幫助信息,包括函數(shù)的基本功能、調(diào)用方法以及參數(shù)說明。(注:希爾伯特矩陣中的元素為,其中分別為該元素的行下標(biāo)和列下標(biāo)。普通意義上的希爾伯特矩陣為方陣,MATLAB創(chuàng)建n×n希爾伯特矩陣的指令為hilb(n)。本例創(chuàng)建m×n的廣義希爾伯特矩陣)。編寫文件名為gyhilb的函數(shù)文件:functionb=gyhilb(m,n)%GYHILBproduceageneralizedhilbertmatrix%b=gyhilb(m,n)生成一個(m×n)廣義希爾伯特矩陣%b=gyhilb(n)生成一個(n×n)希爾伯特方陣%gyhilb(m,n)只顯示生成的矩陣結(jié)果而不輸出矩陣名ifnargin==1n=m;elseifnargin==0error('請給輸入宗量賦值')elseifnargin>2error('輸入宗量太多')endifnargout>1error('輸出宗量太多')end【例3-12】編寫函數(shù)文件產(chǎn)生擴展希爾伯特矩陣a=zeros(m,n);%預(yù)定義變量ifn==ma=hilb(n);elsefork=1:mforl=1:na(k,l)=1/(k+l+1);endendendifnargout==1b=a;elseifnargout==0disp(a)endend【例3-12】編寫函數(shù)文件產(chǎn)生擴展希爾伯特矩陣在指令窗中執(zhí)行>>b=gyhilb(3,2)b=0.33330.25000.25000.20000.20000.1667>>gyhilb(4,5)0.33330.25000.20000.16670.14290.25000.20000.16670.14290.12500.20000.16670.14290.12500.11110.16670.14290.12500.11110.1000>>b=gyhilb(4)b=1.00000.50000.33330.25000.50000.33330.25000.20000.33330.25000.20000.1667
0.25000.20000.16670.1429【例3-12】編寫函數(shù)文件產(chǎn)生擴展希爾伯特矩陣【說明】從結(jié)構(gòu)上看,函數(shù)文件比腳本文件多一個“函數(shù)申明行”,其余各部分相同。如果函數(shù)文件只有一個輸出變量時,可以省略函數(shù)行輸出宗量的中括號。建議用戶將第一條注釋用英文表達,便于MATLAB的關(guān)鍵詞檢索。MATLAB的函數(shù)文件不僅可以被用戶在指令窗里調(diào)用,還可以被其自身調(diào)用,即可以實現(xiàn)遞歸調(diào)用?!纠?-13】編寫函數(shù)文件計算n!,其中n自然數(shù)。functionf=ffactor(n)%FFACTORCalculaten!%nn為自然數(shù)ifnargin~=1error('輸入變量個數(shù)太多')endifnargout>1error('輸出變量個數(shù)太多')endifabs(n-floor(n))>eps|n<0%判斷n是不是自然數(shù),如果不是
error('輸入變量n應(yīng)為自然數(shù)')endifn>1f=ffactor(n-1)*n;elsef=1;endend編寫文件名為factor的函數(shù)文件:在指令窗中執(zhí)行:>>f=ffactor(20)f=2.4329e+018或者用戶編寫文件名為exm3_13的腳本文件:fori=1:10f(i)=ffactor(i);endf在指令窗中執(zhí)行該腳本文件,可以同時計算1到10各個自然數(shù)的階乘:>>exm3_13f=Columns1through7126241207205040Columns8through10403203628803628800【例3-13】編寫函數(shù)文件計算n!,其中n自然數(shù)。采用遞歸結(jié)構(gòu)編寫的程序簡潔明了,但執(zhí)行時費時太多,建議用戶盡量少用遞歸式編程。3.3.3局部變量和全局變量用MATLAB語言編寫的文件有腳本文件和函數(shù)文件之分,在文件執(zhí)行過程中,如果沒有特別聲明,腳本文件運行后產(chǎn)生的變量存放在基本工作空間,函數(shù)文件運行過程中產(chǎn)生的變量存放于函數(shù)工作空間。1.局部變量(LocalVariables)由于函數(shù)工作空間中的變量其影響范圍只是局限在自身函數(shù)工作空間內(nèi),一旦該函數(shù)文件運行結(jié)束,它們將自動被刪除。由于其在空間上的局限性,這一類型的變量稱為局部變量。
2.全局變量(GlobalVariables)MATLAB允許幾個不同的函數(shù)空間以及基本工作空間共享一個變量,被共享的變量稱為全局變量。全局變量是用MATLAB提供的global指令來設(shè)置的,格式如下:globalXYZ其中X,Y,Z為希望定義的全局變量,中間用空格隔開。每個希望共享全局變量的函數(shù)或MATLAB基本工作空間,必須逐個用global指令對具體變量加以專門定義。沒采用global指令定義的函數(shù)或基本工作空間,將無權(quán)使用全局變量。如果某個函數(shù)的執(zhí)行使全局變量的內(nèi)容發(fā)生變化,那么其他函數(shù)空間以及基本工作空間中的同名變量也就隨之變化。除非與全局變量聯(lián)系的所有工作空間都被刪除,否則全局變量依然存在?!菊f明】對全局變量的定義必須在該變量被使用之前進行。建議把全局變量的定義放在腳本文件和函數(shù)文件的首行位置。如果在當(dāng)前工作空間已經(jīng)存在了相同的變量,系統(tǒng)將會給出警告,說明如果將該變量定義為全局變量,可能會使變量的值發(fā)生改變。為了提高文件的可讀性,建議使用大寫字母命名全局變量。由于全局變量影響了函數(shù)的封裝性,不提倡使用全局變量?!纠?-14】global指令定義全局變量示例。
編寫計算圓周周長和面積的函數(shù)文件ffun_SC:
function[C,S]=ffun_SC%FFUN_SCCalculatetheareaandthetheperimeterofacircleglobalRC=2*pi*R;S=pi*R^2;end編寫腳本文件并命名為exm3_14:clearglobalRR=4;[C,S]=ffun_SC在指令窗中執(zhí)行指令:>>exm3_14C=25.1327S=50.26553.4MATLAB函數(shù)類別和句柄函數(shù)函數(shù)文件是擴展名為.m的M文件中的一種,而函數(shù)文件又可以被細分為主函數(shù)、子函數(shù)、私用函數(shù)、匿名函數(shù)和內(nèi)聯(lián)函數(shù)等。本文只介紹主函數(shù)、子函數(shù)和內(nèi)聯(lián)函數(shù),并簡要介紹函數(shù)句柄。3.4.1主函數(shù)MATLAB允許一個函數(shù)文件包含多個函數(shù)。其中第一個出現(xiàn)的函數(shù)被稱為主函數(shù)(Primaryfunction),該文件中的其他函數(shù)都被稱為子函數(shù)(Subfunction)。保存時所用函數(shù)文件名與主函數(shù)定義名相同。外部程序只能對主函數(shù)進行調(diào)用。主函數(shù)的特點為:一般為“與保存文件名相同”的那個函數(shù)。在當(dāng)前目錄、搜索路徑上,列出文件名的函數(shù)。在指令窗中或其他函數(shù)中,可以直接被調(diào)用的函數(shù)。M函數(shù)文件中,有第一個function引導(dǎo)的函數(shù)。采用helpfunctionname可獲取函數(shù)所攜帶的幫助信息。3.4.2子函數(shù)子函數(shù)的特點為:子函數(shù)不獨立存在,只能寄生在主函數(shù)中。在函數(shù)文件中,由非第一個function引導(dǎo)的函數(shù)。一個函數(shù)文件可以包含多個子函數(shù)。同一函數(shù)文件的主函數(shù)、子函數(shù)的工作空間彼此獨立,各函數(shù)之間的信息或通過輸入輸出宗量傳遞,或通過全局變量傳遞。子函數(shù)只能被其所在的主函數(shù)和其他“同居”子函數(shù)調(diào)用。子函數(shù)可以出現(xiàn)在主函數(shù)中的任何位置,其位置先后與調(diào)用次序無關(guān)。在函數(shù)文件中,任何指令通過函數(shù)名對函數(shù)進行調(diào)用時,子函數(shù)的優(yōu)先級別僅次于內(nèi)裝函數(shù)。采用helpfunctionname/subfunctionname可獲取子函數(shù)所攜帶的幫助信息。3.4.3內(nèi)聯(lián)函數(shù)MATLAB除了可以用function關(guān)鍵字開頭的文件定義函數(shù),還可以通過建立內(nèi)聯(lián)函數(shù)的方法建立函數(shù)文件,內(nèi)聯(lián)函數(shù)(Inlinefunction)較之前的函數(shù)文件而言,創(chuàng)建方式比較簡單。內(nèi)聯(lián)函數(shù)使得MATLAB的“泛函”指令具備了適應(yīng)各種運算的能力。1.建立內(nèi)聯(lián)函數(shù)建立內(nèi)聯(lián)函數(shù)的指令是inline(),格式如下:?inline('EXPR')?以字符串EXPR創(chuàng)建內(nèi)聯(lián)函數(shù),如不指出變量,MATLAB將以指令findsym()指定變量為函數(shù)輸入宗量。用戶可以調(diào)用指令argnames()來查看內(nèi)聯(lián)函數(shù)的輸入宗量。指令vectorize()使得內(nèi)聯(lián)函數(shù)適用于數(shù)組運算規(guī)則,格式為:?vectorize(EXPR)?使得內(nèi)聯(lián)函數(shù)適用于數(shù)組計算【例3-15】運用內(nèi)聯(lián)函數(shù)實現(xiàn)(1)創(chuàng)建內(nèi)聯(lián)函數(shù):>>clear,F=inline('a*exp(2*x)*cos(y)')F=Inlinefunction:F(a,x,y)=a*exp(2*x)*cos(y)(2)查看內(nèi)聯(lián)函數(shù)的輸入宗量:>>argnames(F)ans='a''x'
'y'(3)使其適應(yīng)數(shù)組運算:>>FF=vectorize(F)FF=Inlinefunction:FF(a,x,y)=a.*exp(2.*x).*cos(y)(4)令a=3,計算和的值:>>FF(3,[12],[pi/3pi/7])ans=11.0836147.5737【說明】:'EXPR'是字符串;EXPR必須是不包含賦值號“=”的表達式?!纠?-15】運用內(nèi)聯(lián)函數(shù)實現(xiàn)2.計算內(nèi)聯(lián)函數(shù)的值指令feval()可以調(diào)用內(nèi)聯(lián)函數(shù)并進行計算,其格式如下:?y=feval(FIN,x1,x2…)?執(zhí)行內(nèi)聯(lián)函數(shù)FIN指定的計算,其中x1,x2…為傳遞給函數(shù)的參數(shù)值,它們的含義以及排列次序均與內(nèi)聯(lián)函數(shù)的輸入宗量含義及排列次序一致。y為計算結(jié)果?!纠?-16】內(nèi)聯(lián)函數(shù)求值。>>clear,f=inline('b*sin(3^x+z)')%創(chuàng)建內(nèi)聯(lián)函數(shù)f=Inlinefunction:f(b,x,z)=b*sin(3^x+z)>>fy=feval(f,2,1,3)%使用函數(shù)feval()計算結(jié)果fy=-0.5588>>f(2,1,3)%也可以直接計算ans=-0.55883.4.4函數(shù)句柄函數(shù)句柄(FunctionHandle)是MATLAB的一種數(shù)據(jù)類型。它攜帶“相應(yīng)函數(shù)創(chuàng)建句柄時的路徑、視野、函數(shù)名以及可能的重載方式”。函數(shù)句柄并不伴隨函數(shù)文件的被創(chuàng)建、被調(diào)用而自動初始。用戶可以通過兩種方式為一個函數(shù)定義句柄:一是利用符號“@”,二是利用轉(zhuǎn)換函數(shù)str2func()。對函數(shù)句柄的觀察需要借助指令functions()來實現(xiàn)。引入函數(shù)句柄后,用戶可以調(diào)用函數(shù)如同調(diào)用變量一樣方便。由于普通函數(shù)文件在調(diào)用時,MATLAB都要為其進行全面的路徑搜索,而函數(shù)句柄內(nèi)部提供了路徑搜索的全部信息,因此可以提高函數(shù)調(diào)用的速度,尤其是在反復(fù)調(diào)用的情況下效果更加明顯。另外,函數(shù)句柄可以提高軟件重用性,擴大子函數(shù)和私用函數(shù)的可調(diào)用性,也可迅速獲得同名重載函數(shù)的位置、類型信息?!纠?-17】(續(xù)例3-12)為gyhilb函數(shù)文件創(chuàng)建函數(shù)句柄,并觀察其內(nèi)涵。(1)創(chuàng)建函數(shù)句柄
將gyhilb函數(shù)文件設(shè)置在搜索路徑上,并執(zhí)行:
>>clear,hm=@gyhilb
hm=
@gyhilb
(2)類型判斷
>>class(hm)
ans=
function_handle(3)借助指令functions()觀察內(nèi)涵
>>F=functions(hm)
F=
function:'gyhilb'
type:'simple'
file:'L:\matlab2011a\ch3\gyhilb.m'
(4)句柄的調(diào)用方法之一
>>M1=hm(3,4)
M1=
0.33330.25000.20000.1667
0.25000.20000.16670.1429
0.20000.16670.14290.1250(5)句柄的調(diào)用方法之二
>>M2=feval(hm,3,4)(結(jié)果同上)【例3-17】(續(xù)例3-12)為gyhilb函數(shù)文件創(chuàng)建函數(shù)句柄,并觀察其內(nèi)涵。用戶可以改變當(dāng)前目錄,比如將L:\matlab2011a\bin設(shè)置為當(dāng)前目錄,然后在指令窗中執(zhí)行:
>>gyhilb(3)
>>M=hm(3)
M=
1.00000.50000.3333
0.50000.33330.2500
0.33330.25000.2000【說明】指令hm=@hilb的功能,可以用hm=str2func('hilb')替換。用戶在創(chuàng)建函數(shù)的句柄時,必須保證該函數(shù)處于“當(dāng)前視野”【例3-17】(續(xù)例3-12)為gyhilb函數(shù)文件創(chuàng)建函數(shù)句柄,并觀察其內(nèi)涵。functionHr=exm3_18(flag)%EXM3_18Demoforhandlesofprimaryfunctions,subfunctionsandfunctionhandle%flag只能取字符串'line'或者'circle'%Hr子函數(shù)cirline的句柄t=linspace(0,2*pi,150);x=sin(t);y=cos(t);Hr=@cirline;%創(chuàng)建子函數(shù)cirline的函數(shù)句柄feval(Hr,flag,x,y,t)%函數(shù)宏指令,調(diào)用子函數(shù)%----subfunction----functioncirline(wd,x,y,t)%cirline(wd,x,y,t)位于主函數(shù)exm3_18內(nèi)部的子函數(shù)%wd可以取字符串'line'或者'circle‘%t畫線用的獨立參變量;x,y由t產(chǎn)生的坐標(biāo)點【例3-18】編寫一個含有子函數(shù)的函數(shù)文件,并創(chuàng)建子函數(shù)句柄,并利用子函數(shù)句柄在指令窗中執(zhí)行子函數(shù)。switchwdcase'line'plot(t,x,'b',t,y,'r','LineWidth',2)case'circle'plot(x,y,'-r','LineWidth',3)axisequalotherwiseerror('輸入宗量只能取“l(fā)ine”和“circle”!')endshg%圖形窗顯示在前臺
endend【例3-18】編寫一個含有子函數(shù)的函數(shù)文件,并創(chuàng)建子函數(shù)句柄,并利用子函數(shù)句柄在指令窗中執(zhí)行子函數(shù)。(2)把exm3_18.m保存在MATLAB的搜索路徑上,然后在指令窗中執(zhí)行下列指令:>>HH=exm3_18('circle')HH=@exm3_18/cirline得到如圖3.4所示的圖:(3)直接利用創(chuàng)建的子函數(shù)句柄,在指令窗中執(zhí)行下列指令,調(diào)用子函數(shù):>>t=linspace(0,2*pi,8);>>x=cos(t);y=sin(t);>>HH('circle',x,y,t)得到如圖3.5所示的圖:【例3-18】編寫一個含有子函數(shù)的函數(shù)文件,并創(chuàng)建子函數(shù)句柄,并利用子函數(shù)句柄在指令窗中執(zhí)行子函數(shù)?!菊f明】創(chuàng)建子函數(shù)句柄指令位于主函數(shù)體內(nèi),因此,只有當(dāng)主函數(shù)被執(zhí)行后子函數(shù)句柄才被創(chuàng)建,當(dāng)用戶在工作空間看到被創(chuàng)建的子函數(shù)句柄HH后,才能利用指令在指令
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 贛州師范高等專科學(xué)?!墩撐囊?guī)范教育》2023-2024學(xué)年第一學(xué)期期末試卷
- 《急診科護理查房》課件
- 三年級數(shù)學(xué)上冊六平移旋轉(zhuǎn)和軸對稱平移和旋轉(zhuǎn)說課稿蘇教版
- 2021一建考試《建筑工程實務(wù)》題庫試卷考點題庫及參考答案解析四
- 《論壇推廣》課件
- 小學(xué)生生物安全課件下載
- 一元一次討論移項-課件
- 火災(zāi)現(xiàn)場安全課件
- 《激光在眼科的運用》課件
- 小學(xué)生武警教育課件
- 61850基礎(chǔ)技術(shù)介紹0001
- 陶瓷色料的技術(shù)PPT課件
- 幼兒園食品安全工作計劃四篇
- 課程設(shè)計YA32-350型四柱萬能液壓機液壓系統(tǒng)設(shè)計
- 圍堰高噴防滲墻工程監(jiān)理實施細則
- (精心整理)系動詞練習(xí)題
- 體彩排列五歷史數(shù)據(jù)
- 中國工業(yè)數(shù)據(jù)庫介紹
- 弱電智能化設(shè)計服務(wù)建議書(共35頁)
- 中國銀監(jiān)會關(guān)于規(guī)范中長期貸款還款方式的通知
- 通信工程外文文獻(共12頁)
評論
0/150
提交評論