版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
流程控制1選擇結(jié)構(gòu)如前所述,當(dāng)人們判斷某一條件是否滿(mǎn)足,根據(jù)判斷的結(jié)果來(lái)選擇不同的解決問(wèn)題的方法時(shí),就需要使用選擇結(jié)構(gòu)。和C語(yǔ)言類(lèi)似,MATLAB的條件判斷可以使用if語(yǔ)句或者switch語(yǔ)句。
1.1if語(yǔ)句if語(yǔ)句的基本語(yǔ)法結(jié)構(gòu)有三種,分別如下:(1)if(關(guān)系運(yùn)算表達(dá)式) MATLAB語(yǔ)句end
這種形式的選擇結(jié)構(gòu)表示,當(dāng)關(guān)系運(yùn)算表達(dá)式計(jì)算的結(jié)果為邏輯真的時(shí)候,執(zhí)行MATLAB語(yǔ)句,這里的MATLAB語(yǔ)句可以是一個(gè)MATLAB表達(dá)式,也可以是多個(gè)MATLAB表達(dá)式。在MATLAB語(yǔ)句的結(jié)尾處,必須有關(guān)鍵字end。
(2)if(關(guān)系運(yùn)算表達(dá)式) MATLAB語(yǔ)句Aelse MATLAB語(yǔ)句Bend
這種選擇結(jié)構(gòu)表示,當(dāng)關(guān)系運(yùn)算表達(dá)式的計(jì)算結(jié)果為邏輯真的時(shí)候,執(zhí)行MATLAB語(yǔ)句A,否則執(zhí)行MATLAB語(yǔ)句B,在語(yǔ)句B的結(jié)尾必須具有關(guān)鍵字end。(3)if(關(guān)系運(yùn)算表達(dá)式a) MATLAB語(yǔ)句A
elseif(關(guān)系運(yùn)算表達(dá)式b) MATLAB語(yǔ)句Belse(關(guān)系運(yùn)算表達(dá)式c)
end
這種選擇結(jié)構(gòu)可以判斷多條關(guān)系運(yùn)算表達(dá)式的計(jì)算結(jié)果,然后按照?qǐng)?zhí)行的邏輯關(guān)系執(zhí)行相應(yīng)的語(yǔ)句。根據(jù)類(lèi)似的C語(yǔ)言知識(shí)或者前面兩種選擇結(jié)構(gòu)的介紹判斷這種結(jié)構(gòu)的執(zhí)行方式?!璱f(關(guān)系表達(dá)式a) if(關(guān)系表達(dá)式b)MATLAB語(yǔ)句A elseMATLAB語(yǔ)句B endelse if(關(guān)系表達(dá)式c)MATLAB語(yǔ)句C elseMATLAB語(yǔ)句D endend注意:在使用嵌套的選擇結(jié)構(gòu)時(shí),需要小心if語(yǔ)句和end關(guān)鍵字的配對(duì)。和C語(yǔ)言類(lèi)似,if-elseif-else的語(yǔ)句結(jié)構(gòu)也可以嵌套地使用,也就是可以存在這樣的語(yǔ)句結(jié)構(gòu):1.2switch語(yǔ)句另外一種構(gòu)成選擇結(jié)構(gòu)的關(guān)鍵字就是switch。在處理實(shí)際問(wèn)題的時(shí)候,往往要處理多個(gè)分支,這時(shí)如果使用if-else語(yǔ)句處理多分支結(jié)構(gòu)往往使程序變得十分冗長(zhǎng),從而降低了程序的可讀性。switch語(yǔ)句就可以用于處理這種多分支的選擇,它的基本語(yǔ)法結(jié)構(gòu)如下:switch(表達(dá)式) case常量表達(dá)式a:MATLAB語(yǔ)句A case常量表達(dá)式b:MATLAB語(yǔ)句B
case常量表達(dá)式m:MATLAB語(yǔ)句M otherwise:MATLAB語(yǔ)句N(xiāo)end…在switch語(yǔ)句之后的表達(dá)式可以是一個(gè)數(shù)值類(lèi)型表達(dá)式或者是一個(gè)數(shù)值類(lèi)型的變量,當(dāng)這個(gè)表達(dá)式的值同case后面的某一個(gè)常量表達(dá)式相等時(shí),則執(zhí)行該case后面的常量表達(dá)式后面的語(yǔ)句。注意:
MATLAB的switch和C語(yǔ)言的switch語(yǔ)句結(jié)構(gòu)不同。在C語(yǔ)言中,每一個(gè)case后面的語(yǔ)句中必須包含類(lèi)似break語(yǔ)句的流程控制語(yǔ)句,否則程序會(huì)依次執(zhí)行符合條件的case語(yǔ)句后面的每一個(gè)case分支。但是在MATLAB中就不必如此,程序僅僅執(zhí)行符合條件的case分支。補(bǔ)充例題3中需要用戶(hù)在執(zhí)行程序的過(guò)程中輸入一個(gè)字符串,switch語(yǔ)句根據(jù)用戶(hù)的輸入判斷執(zhí)行相應(yīng)的case分支。若沒(méi)有符合條件的case分支,則switch執(zhí)行otherwise后面的語(yǔ)句。若switch結(jié)構(gòu)中沒(méi)有定義otherwise及其相應(yīng)的代碼,則程序不會(huì)進(jìn)行任何操作,而是直接退出switch結(jié)構(gòu)。提示:在處理以字符串變量或者常量參與的關(guān)系判斷操作時(shí),使用switch結(jié)構(gòu)要比if-else結(jié)構(gòu)效率高一些。由于MATLAB的switch結(jié)構(gòu)沒(méi)有C語(yǔ)言的fall-through特性,所以,如果需要針對(duì)多個(gè)條件而使用同一個(gè)case分支的時(shí)候,需要使用元胞數(shù)組與之配合。例子
4switch結(jié)構(gòu)使用示例——switch_examp2.m。001 clearall002003 var=input('InputaNumer:');004 switchvar005 case1006 disp('1')007 case{2,3,4}008 disp('2or3or4')009 case5010 disp('5')011 otherwise012 disp('somethingelse')013 end例子4運(yùn)行的方法和效果如下:>>switch_examp2InputaNumer:11>>switch_examp2InputaNumer:32or3or4>>switch_examp2InputaNumer:7somethingelse例子4代碼的核心部分為007行,這里使用元胞數(shù)組增加判斷條件的個(gè)數(shù),當(dāng)輸入的數(shù)字為2、3或者4時(shí),switch結(jié)構(gòu)將使用同一個(gè)case分支進(jìn)行判斷、計(jì)算。注意:從代碼的完整性和可靠性角度出發(fā),在使用switch語(yǔ)句時(shí),一定要包含otherwise分支,這是一種良好的編程習(xí)慣。2循環(huán)結(jié)構(gòu)在解決很多問(wèn)題的時(shí)候需要使用循環(huán)結(jié)構(gòu),例如求解數(shù)列的和或者進(jìn)行某種迭代法求解數(shù)值方程時(shí),都需要循環(huán)結(jié)構(gòu)配合完成計(jì)算。在MATLAB中,包含兩種循環(huán)結(jié)構(gòu),一種是循環(huán)次數(shù)不確定的while循環(huán),而另一種是循環(huán)次數(shù)確定的for循環(huán)。
1.while循環(huán)結(jié)構(gòu)while語(yǔ)句可以用來(lái)實(shí)現(xiàn)“當(dāng)”型的循環(huán)結(jié)構(gòu),它的一般形式如下:while(表達(dá)式)MATLAB語(yǔ)句end
當(dāng)表達(dá)式為真時(shí),循環(huán)將執(zhí)行由語(yǔ)句構(gòu)成的循環(huán)體,其特點(diǎn)是先判斷循環(huán)條件,如果循環(huán)條件成立,即表達(dá)式運(yùn)算結(jié)果為“真”,再執(zhí)行循環(huán)體。循環(huán)體執(zhí)行的語(yǔ)句可以是一句也可以是多句,在MATLAB語(yǔ)句之后必須使用關(guān)鍵字end作為整個(gè)循環(huán)結(jié)構(gòu)的結(jié)束。另外,在循環(huán)過(guò)程中一定要能夠改變關(guān)系表達(dá)式或者布爾類(lèi)型變量的值,或者使用其他方法來(lái)跳出循環(huán),否則會(huì)陷入死循環(huán)(無(wú)法正常退出的循環(huán)叫作死循環(huán))。例子5
使用while語(yǔ)句求解 。001 i=1;002 sum=0;003 while(i<=1000)004 sum=sum+i;005 i=i+1;006 end007 str=['計(jì)算結(jié)果為:',num2str(sum)];008 disp(str)例子5的運(yùn)行結(jié)果為
>>while_example
計(jì)算結(jié)果為:500500
例子5的使用了while循環(huán)結(jié)構(gòu),在循環(huán)結(jié)構(gòu)中進(jìn)行了累加的操作。需要注意的是,在MATLAB中沒(méi)有類(lèi)似C語(yǔ)言的++或者+=等運(yùn)算操作符,因此在進(jìn)行諸如累加或者遞減的運(yùn)算時(shí),不得不給出完整的表達(dá)式。另外,例子5求數(shù)列和的算法的運(yùn)算效率很低,在MATLAB中不要使用這樣的結(jié)構(gòu)完成類(lèi)似的運(yùn)算,而需要采用向量化的計(jì)算。注意:
while循環(huán)結(jié)構(gòu)的關(guān)系表達(dá)式可以是某個(gè)數(shù)據(jù)變量或者常量,這時(shí),將按照非零值為邏輯真進(jìn)行相應(yīng)的操作。另外,在進(jìn)行上述操作時(shí),若數(shù)據(jù)變量為空矩陣,則while語(yǔ)句將空矩陣作為邏輯假處理,也就是說(shuō),在whileAMATLAB語(yǔ)句S1end結(jié)構(gòu)中,若A為空矩陣,則MATLAB語(yǔ)句S1永遠(yuǎn)不會(huì)被執(zhí)行。
2.for循環(huán)結(jié)構(gòu)使用for語(yǔ)句構(gòu)成循環(huán)是最靈活、簡(jiǎn)便的方法,不過(guò),使用for語(yǔ)句循環(huán)需要預(yù)先知道循環(huán)體執(zhí)行的次數(shù),所以這種循環(huán)一般叫作確定循環(huán)。在MATLAB中for循環(huán)的基本結(jié)構(gòu)如下:forindex=start:increment:end MATLAB語(yǔ)句end其中,index的取值取決于start和end的值,一般地,這里通常使用等差的數(shù)列向量,參見(jiàn)例子6。例子6
使用for語(yǔ)句求解 。001 sum=0;002 fori=1:1000003 sum=sum+i;004 end 005 str=['計(jì)算結(jié)果為:',num2str(sum)];006 disp(str)例子6運(yùn)行的結(jié)果為>>for_example計(jì)算結(jié)果為:500500
在例子6中,使用了確定次數(shù)的for循環(huán)結(jié)構(gòu),循環(huán)次數(shù)使用行向量進(jìn)行控制,而且索引值i按照默認(rèn)的數(shù)值1進(jìn)行遞增。在for循環(huán)語(yǔ)句中,不僅可以使用行向量進(jìn)行循環(huán)迭代的處理,也可以使用矩陣作為循環(huán)次數(shù)的控制變量,這時(shí)循環(huán)的索引值將直接使用矩陣的每一列,循環(huán)的次數(shù)為矩陣的列數(shù),參見(jiàn)例子7。例子7for循環(huán)示例。001 A=rand(3,4);002003 fori=A004 sum=mean(i)005 end例子7運(yùn)行的結(jié)果為>>for_matricessum=0.2728sum=0.6649sum=0.4275sum=0.5220例子7盡管只有短短的幾行,但是使用了一個(gè)矩陣作為循環(huán)的索引值,于是,循環(huán)結(jié)果就分別計(jì)算矩陣的每一列元素的均值。和其他高級(jí)語(yǔ)言類(lèi)似,MATLAB的循環(huán)結(jié)構(gòu)也可以進(jìn)行嵌套使用,使用嵌套的循環(huán)需要注意for關(guān)鍵字和end關(guān)鍵字之間的配對(duì)使用,根據(jù)高級(jí)語(yǔ)言的一般特性來(lái)推斷其運(yùn)行的方式。3break語(yǔ)句和continue語(yǔ)句在循環(huán)結(jié)構(gòu)中還有兩條語(yǔ)句會(huì)影響程序的流程,這就是break語(yǔ)句和continue語(yǔ)句,這兩條語(yǔ)句的基本功能如下:●當(dāng)break語(yǔ)句使用在循環(huán)體中的時(shí)候,其作用是能夠在執(zhí)行循環(huán)體的時(shí)候強(qiáng)迫終止循環(huán),即控制程序的流程,使其提前退出循環(huán),它的使用方法是
break;●continue語(yǔ)句出現(xiàn)在循環(huán)體中的時(shí)候,其作用是能夠中斷本次的循環(huán)體運(yùn)行,將程序的流程跳轉(zhuǎn)到判斷循環(huán)條件的語(yǔ)句處,繼續(xù)下一次的循環(huán),它的使用方法是
continue;例子8break語(yǔ)句示例——break_example.m。001 i=0;002 j=0;003 k=0;004 fori=1:2005 forj=1:2006 fork=1:2007 if(k==2)008 disp('退出循環(huán)');009 break;010 end011 str=sprintf('I=%d,J=%d,K=%d',i,j,k);012 disp(str);013 end014 end015 end016 disp('程序運(yùn)行結(jié)束');例子8的運(yùn)行結(jié)果如下:>>break_exampleI=1,J=1,K=1退出循環(huán)I=1,J=2,K=1退出循環(huán)I=2,J=1,K=1退出循環(huán)I=2,J=2,K=1退出循環(huán)程序運(yùn)行結(jié)束
break語(yǔ)句的作用是退出當(dāng)前的循環(huán)結(jié)構(gòu)運(yùn)行,所以在例子8中,位于最內(nèi)層循環(huán)的break語(yǔ)句執(zhí)行的結(jié)果是退出了最內(nèi)層的循環(huán)k,位于外層的循環(huán)i和j還是都運(yùn)行完畢了。例子9continue語(yǔ)句示例。001 i=0;002 fori=1:6003 if(i>3)004 continue005 else006 str=sprintf('I=%d',i);007 disp(str);008 end009 end010 str=sprintf('循環(huán)結(jié)束I=%d',i);011 disp(str);例子9的運(yùn)行結(jié)果如下:>>continue_exampleI=1I=2I=3循環(huán)結(jié)束I=6continue語(yǔ)句的作用在例子9中得到了充分說(shuō)明,該語(yǔ)句終止當(dāng)前的循環(huán),然后繼續(xù)下一次循環(huán)運(yùn)算,直到所有的循環(huán)迭代運(yùn)算結(jié)束為止。4提高運(yùn)算性能
M語(yǔ)言和其他的高級(jí)語(yǔ)言不同,由于采用了解釋型語(yǔ)言,所以M語(yǔ)言的執(zhí)行效率肯定低于編譯型語(yǔ)言(例如C語(yǔ)言)。然而,隨著MATLAB版本的不斷升級(jí),再加之合理利用MATLAB向量運(yùn)算等特點(diǎn)可以較大幅度地提高M(jìn)語(yǔ)言代碼的執(zhí)行效率。在本小節(jié)結(jié)合一些具體的例子來(lái)講述M語(yǔ)言編程以及MATLAB軟件本身在提高程序執(zhí)行效率方面的一些特性。
1.向量化運(yùn)算首先,希望讀者牢記這樣一點(diǎn),MATLAB最初的目的是提供便利的矩陣數(shù)據(jù)操作能力。所以在大多數(shù)的應(yīng)用程序中,不要使用循環(huán)結(jié)構(gòu)操作矩陣的元素,應(yīng)直接使用矩陣元素的索引或者矩陣運(yùn)算的函數(shù),這樣做不僅能夠提高代碼的執(zhí)行效率,而且還能夠提高程序的可讀性,這就是所謂的向量化的運(yùn)算,也就是說(shuō),盡量將使用while循環(huán)或者for循環(huán)的語(yǔ)句結(jié)構(gòu)轉(zhuǎn)換成等價(jià)的向量或者矩陣運(yùn)算,以提高程序的運(yùn)算速度,參見(jiàn)例子10。例子10
向量化運(yùn)算——array_vs_loops.m。001 Mass=rand(5,10000);002 Length=rand(5,10000);003 Width=rand(5,10000);004 Height=rand(5,10000);005 006 [rows,cols]=size(Mass);007 008 disp([char(10),'使用數(shù)組運(yùn)算:'])009 tic010 Density=Mass./(Length.*Width.*Height);011 toc
012013 disp([char(10),'使用循環(huán)結(jié)構(gòu):'])014 tic;015 forI=1:rows016 forJ=1:cols017 Density(I)=Mass(I,J)/(Length(I,J)*Width(I,J)*Height(I,J));018 end019 end020 toc
例子10比較了循環(huán)結(jié)構(gòu)和數(shù)組運(yùn)算的執(zhí)行效率,程序中分別在010行使用數(shù)組運(yùn)算和在015~019行使用循環(huán)結(jié)構(gòu)完成了同樣的工作。程序的運(yùn)行結(jié)果如下:>>array_vs_loops使用數(shù)組運(yùn)算:elapsed_time=*使用循環(huán)結(jié)構(gòu):elapsed_time=*
2.預(yù)分配存儲(chǔ)空間另外一種能夠提高運(yùn)算效率的方法就是進(jìn)行內(nèi)存變量存儲(chǔ)空間的預(yù)分配,首先察看例子11。例子11內(nèi)存預(yù)分配的例子——pre_allocate.m。001 disp([char(10),'使用內(nèi)存預(yù)分配:'])002 pre_allo=zeros(10000,1);003 tic;004 forI=1:10000005 pre_allo(I)=rand(1);006 end007 toc008 009 disp([char(10),'不使用內(nèi)存預(yù)分配:'])010 tic;011 forJ=1:10000012 not_pre_allo(J)=rand(1);013 end014 toc
例子11的執(zhí)行結(jié)果如下:
>>pre_allocate使用內(nèi)存預(yù)分配:elapsed_time=*不使用內(nèi)存預(yù)分配:elapsed_time=*上面兩種不同的運(yùn)算惟一的區(qū)別就是程序002行,執(zhí)行這行語(yǔ)句之后,MATLAB自動(dòng)分配了10000個(gè)連續(xù)的內(nèi)存空間用于存儲(chǔ)數(shù)據(jù),MATLAB將一次創(chuàng)建足夠的存儲(chǔ)空間,然后依次賦值。而后者not_pre_alloc變量沒(méi)有進(jìn)行相應(yīng)的操作,所以帶來(lái)了兩次運(yùn)算結(jié)果的不同。在不使用內(nèi)存預(yù)分配的運(yùn)算中,MATLAB是如何進(jìn)行操作的呢?當(dāng)I=1時(shí),MATLAB將使用一小塊長(zhǎng)度為一個(gè)單元大小的內(nèi)存保存一位隨機(jī)數(shù)。當(dāng)I=2時(shí),MATLAB尋找一塊兩單元大小的內(nèi)存區(qū),一個(gè)單元放第一個(gè)隨機(jī)數(shù),第二個(gè)放另外一個(gè)隨機(jī)數(shù)?!?dāng)I=10000時(shí),MATLAB尋找一塊容納10000單元的內(nèi)存區(qū)存放以前的9999個(gè)隨機(jī)數(shù),同時(shí)把最新的一個(gè)隨機(jī)數(shù)加入進(jìn)去。代碼運(yùn)行的結(jié)果造成了存儲(chǔ)空間的浪費(fèi),降低了程序的執(zhí)行速度。所以,在編寫(xiě)M語(yǔ)言程序的時(shí)候需要盡量使用內(nèi)存的預(yù)分配,而少使用或者不使用數(shù)組內(nèi)存空間的自動(dòng)擴(kuò)充方式。MATLAB針對(duì)不同的數(shù)據(jù)類(lèi)型有不同的內(nèi)存預(yù)分配函數(shù),見(jiàn)表1。表1內(nèi)存預(yù)分配函數(shù)表1中說(shuō)明了不同數(shù)據(jù)類(lèi)型所要使用的內(nèi)存預(yù)分配函數(shù),其中結(jié)構(gòu)類(lèi)型的數(shù)組需要兩個(gè)函數(shù)配合使用,利用struct函數(shù)構(gòu)造結(jié)構(gòu),而使用repmat函數(shù)創(chuàng)建數(shù)組。對(duì)于非雙精度類(lèi)型的數(shù)據(jù),例如整數(shù)類(lèi)型或者單精度類(lèi)型,進(jìn)行內(nèi)存的預(yù)分配時(shí),需要使用相應(yīng)的構(gòu)造函數(shù)或者類(lèi)型轉(zhuǎn)換函數(shù),例如:
Y=int16(zeros(1:10000));
在上面的表達(dá)式中創(chuàng)建了連續(xù)的10000個(gè)16位整數(shù)的存儲(chǔ)空間。當(dāng)預(yù)先分配的內(nèi)存空間無(wú)法容納數(shù)據(jù)時(shí),則可以通過(guò)repmat函數(shù)來(lái)擴(kuò)充數(shù)組的存儲(chǔ)空間。
3.MATLAB加速器盡管利用了上述的特性可以明顯提高M(jìn)語(yǔ)言的運(yùn)行效率,但是在同等條件下,M語(yǔ)言的效率還是無(wú)法和第四代高級(jí)編程語(yǔ)言的執(zhí)行效率相媲美,于是,在MATLAB6.5版本中,新增加了MATLAB性能加速器這樣一個(gè)新特性。MATLAB性能加速器能夠明顯改善循環(huán)結(jié)構(gòu)、內(nèi)建函數(shù)調(diào)用等方面的運(yùn)行效率,特別是在處理循環(huán)迭代次數(shù)確定的for循環(huán)結(jié)構(gòu)中,其運(yùn)算速度較早期的MATLAB版本有很大的提高,在表2中總結(jié)了MATLAB加速器能夠發(fā)揮作用的M語(yǔ)言元素。表2加速器能夠影響的M語(yǔ)言元素表3性能加速器不起作用的M語(yǔ)言元素3腳本文件腳本文件是最簡(jiǎn)單的一種M語(yǔ)言文件,在本章前面章節(jié)的例子中都使用了腳本文件。所謂腳本文件,就是由一系列的MATLAB指令和命令組成的純文本格式的M文件,執(zhí)行腳本文件時(shí),文件中的指令或者命令按照出現(xiàn)在腳本文件中的順序依次執(zhí)行。腳本文件沒(méi)有輸入?yún)?shù),也沒(méi)有輸出參數(shù),執(zhí)行起來(lái)就像早期的DOS操作系統(tǒng)的批處理文件一樣,而腳本文件處理的數(shù)據(jù)或者變量必須在MATLAB的公共工作空間中。例子12
腳本文件示例。001 %注釋行002 %M腳本文件示例003 %"flowerpetal"004 %以下為代碼行005 %計(jì)算006 theta=-pi:0.01:pi;007 rho(1,:)=2*sin(5*theta).^2;008 rho(2,:)=cos(10*theta).^3;009 rho(3,:)=sin(theta).^2;010 rho(4,:)=5*cos(3.5*theta).^3;011 fork=1:4012 %圖形輸出013 subplot(2,2,k)014 polar(theta,rho(k,:))015 end016 disp('程序運(yùn)行結(jié)束!')在MATLAB命令行中運(yùn)行該腳本文件:>>script_example程序運(yùn)行結(jié)束!圖2例子12腳本文件的運(yùn)行結(jié)果仔細(xì)察看例子12的腳本文件,在腳本文件中,主要由注釋行和代碼行組成。M文件的注釋行需要使用%定義符,在%之后的所有文本都認(rèn)為是注釋文本,不過(guò),M文件的注釋定義符僅能影響一行代碼,類(lèi)似于C++語(yǔ)言中的“//”。然而在M語(yǔ)言中,沒(méi)有類(lèi)似C語(yǔ)言的注釋定義符“/*”和“*/”,所以無(wú)法一次定義多行注釋。給程序添加適當(dāng)?shù)淖⑨屖橇己玫木幊塘?xí)慣,希望讀者能夠在日常編程中多多使用。腳本文件中的代碼行都是一些簡(jiǎn)單的MATLAB指令或者命令,這些命令可以用來(lái)完成相應(yīng)的計(jì)算處理數(shù)據(jù)、繪制圖形結(jié)果的操作,也可以在腳本文件中調(diào)用其他的函數(shù)完成復(fù)雜的數(shù)學(xué)運(yùn)算,在例子12中就完成了這些工作。另外,在MATLAB中還有一些指令用來(lái)處理程序和用戶(hù)之間的交互,在表4-4中進(jìn)行了總結(jié)。表4腳本文件中常用的MATLAB指令
MATLAB一般使用腳本文件作為某種批處理文件,其中,有兩個(gè)批處理文件經(jīng)常被MATLAB自動(dòng)調(diào)用,這兩個(gè)腳本文件分別為startup.m和finish.m。
startup.m文件在MATLAB啟動(dòng)時(shí)自動(dòng)被執(zhí)行,用戶(hù)可以自己創(chuàng)建并定義編寫(xiě)該文件,例如在文件中添加物理常量的定義、系統(tǒng)變量的設(shè)置或者M(jìn)ATLAB搜索路徑的設(shè)置。當(dāng)用戶(hù)安裝MATLAB之后,在<MATLABROOT>\toolbox\local路徑下有一個(gè)M文件,名為Starupsav.m,該文件可以看作是startup.m文件的模板,可以修改該文件,然后將其以文件名startup.m的形式保存在<MATLABROOT>\toolbox\local路徑下。與startup.m文件相對(duì)應(yīng)的是finish.m文件,該文件在MATLAB退出時(shí)自動(dòng)執(zhí)行,用戶(hù)可以自己創(chuàng)建并定義編寫(xiě)該文件,例如在文件中添加保存數(shù)據(jù)等指令,這樣可以將每次退出前的工作結(jié)果進(jìn)行保留。同樣,在<MATLABROOT>\toolbox\local路徑下有兩個(gè)文件,分別為finishsav.m和finishdlg.m,這兩個(gè)文件可以用來(lái)作為finish.m文件的模板,相關(guān)的具體內(nèi)容介紹請(qǐng)讀者自己察看相應(yīng)的文件和幫助文檔。4函數(shù)文件4.1基本結(jié)構(gòu)
M函數(shù)文件和腳本文件不同,函數(shù)文件不僅有自己特殊的文件格式,不同的函數(shù)還分別具有自己的工作空間。同其他高級(jí)語(yǔ)言類(lèi)似,M函數(shù)文件也有局部變量和全局變量。讀者首先需要了解的是函數(shù)文件的基本結(jié)構(gòu),參見(jiàn)例子13。例子13
函數(shù)文件示例——average.m。001 functiony=average(x)002 %AVERAGE求向量元素的均值003 %語(yǔ)法:004 %Y=average(X)005 %其中,X是向量,Y為計(jì)算得到向量元素的均值006 %若輸入?yún)?shù)為非向量則出錯(cuò)007 008 %代碼行009 [m,n]=size(x);010 %判斷輸入?yún)?shù)是否為向量011 if(~((m==1)|(n==1))|(m==1&n==1))012 %若輸入?yún)?shù)不是向量,則出錯(cuò)013 error('Inputmustbeavector')014 end015 %計(jì)算向量元素的均值016 y=sum(x)/length(x);在MATLAB命令行中,鍵入下面的指令運(yùn)行例子13的代碼:>>z=1:99;>>y=average(z)y=50M語(yǔ)言函數(shù)文件具有下面的不同部分:*函數(shù)定義行。*在線(xiàn)幫助。*注釋行。*M語(yǔ)言代碼。下面結(jié)合例子13分別說(shuō)明這些部分的構(gòu)成。函數(shù)定義行,例子13的函數(shù)定義行為代碼的001行:
001 functiony=average(x)這一行代碼中包括關(guān)鍵字function、函數(shù)輸出參數(shù)y、函數(shù)的名稱(chēng)average和函數(shù)的輸入?yún)?shù)x。需要讀者注意的是函數(shù)的名稱(chēng),函數(shù)的名稱(chēng)定義要求必須以字符開(kāi)頭,后面可以用字符、數(shù)字和下劃線(xiàn)的組合構(gòu)成函數(shù)名稱(chēng)。MATLAB對(duì)函數(shù)名稱(chēng)的長(zhǎng)度有限定,讀者可以在自己的MATLAB中,通過(guò)執(zhí)行namelengthmax函數(shù)獲取相應(yīng)的數(shù)值。假設(shè)該函數(shù)返回的數(shù)值為N,若函數(shù)的名稱(chēng)長(zhǎng)度超過(guò)了N,則MATLAB使用函數(shù)名稱(chēng)的前N個(gè)字符作為函數(shù)名稱(chēng)。一般推薦將函數(shù)名稱(chēng)用小寫(xiě)的英文字符表示,同時(shí)函數(shù)的M文件名稱(chēng)最好和函數(shù)名稱(chēng)保持一致,若文件名稱(chēng)和函數(shù)名稱(chēng)不一致,則調(diào)用函數(shù)的時(shí)候需要使用文件名稱(chēng)而非函數(shù)名稱(chēng)。
M函數(shù)文件的在線(xiàn)幫助為緊隨在函數(shù)定義行的注釋行。在例子13中,average函數(shù)的在線(xiàn)幫助為002~006行的注釋行。若在MATLAB命令行中鍵入下面的指令:
>>helpaverage在MATLAB的命令窗口中就會(huì)出現(xiàn):
AVERAGE求向量元素的均值語(yǔ)法:
Y=average(X)
其中,X是向量,Y為計(jì)算得到向量元素的均值 若輸入?yún)?shù)為非向量則出錯(cuò)其中,在線(xiàn)幫助中比較重要而且特殊的是在線(xiàn)幫助的第一行,在MATLAB中將這行注釋稱(chēng)為H1幫助行,它是在線(xiàn)幫助的第一行,若使用lookfor函數(shù)查詢(xún)函數(shù)時(shí),僅查詢(xún)并顯示函數(shù)的H1幫助行,例如,在MATLAB命令行中鍵入下面的指令:
>>lookforaverage在MATLAB的命令窗口中就會(huì)出現(xiàn):AVERAGE求向量元素的均值MEANAverageormeanvalue.…由于H1幫助行的特殊作用,所以在用戶(hù)自己定義M函數(shù)文件時(shí),一定要編寫(xiě)相應(yīng)的H1幫助行,對(duì)函數(shù)進(jìn)行簡(jiǎn)明、扼要的說(shuō)明或者解釋。例子13的008、010、012、015行代碼分別是程序具體的注釋行,這些注釋行不會(huì)顯示在在線(xiàn)幫助中,主要原因就是這些注釋行沒(méi)有緊隨在H1幫助行的后面,其中008行的注釋與在線(xiàn)幫助之間有一個(gè)空行。其實(shí)從008行開(kāi)始一直到文件的結(jié)尾都是M函數(shù)文件的代碼行,這些代碼行需要完成具體的算法,實(shí)現(xiàn)用戶(hù)的具體功能。代碼行就是用戶(hù)開(kāi)發(fā)的算法M語(yǔ)言的實(shí)現(xiàn)。4.4.2輸入輸出參數(shù)
M語(yǔ)言函數(shù)文件的輸入、輸出參數(shù)和其他高級(jí)語(yǔ)言的輸入、輸出參數(shù)不同,在定義這些輸入、輸出參數(shù)的時(shí)候不需要指出變量的類(lèi)型,因?yàn)镸ATLAB默認(rèn)這些參數(shù)都使用雙精度類(lèi)型,這樣可以簡(jiǎn)化程序的編寫(xiě)。而且在定義參數(shù)時(shí),也沒(méi)有確定輸入?yún)?shù)的維數(shù)或者尺寸,也就是說(shuō),直接從參數(shù)上無(wú)法判斷輸入來(lái)的是標(biāo)量、向量還是矩陣,只有通過(guò)程序內(nèi)部的具體代碼來(lái)加以判斷。
M語(yǔ)言的函數(shù)文件不僅可以有一個(gè)輸入?yún)?shù)和一個(gè)返回值,還可以為M語(yǔ)言函數(shù)文件定義多個(gè)輸入?yún)?shù)和多個(gè)輸出參數(shù),見(jiàn)例子14。例子14
多個(gè)輸入、輸出參數(shù)的M函數(shù)。001 function[avg,stdev,r]=ourstats(x,tol)002 %OURSTATS多輸入輸出參數(shù)示例003 %該函數(shù)計(jì)算處理矩陣,得到相應(yīng)的均值、004 %標(biāo)準(zhǔn)差和矩陣的秩005 [m,n]=size(x);006 ifm==1007 m=n;008 end009 %Average010 avg=sum(x)/m;011% Sandaddeviation012 stdev=sqrt(sum(x.^2)/m-avg.^2);013 %Rank014 s=svd(x);015 r=sum(s>tol);運(yùn)行例子4-15,在MATLAB命令行中,鍵入下面的指令:>>A=[123;456]A=123456>>[a,s,r]=ourstats(A,0.1)a=2.50003.50004.5000s=1.50001.50001.5000r=2>>ourstats(A,0.1)ans=2.50003.50004.5000>>[a,s]=ourstats(A,0.1)a=2.50003.50004.5000s=1.50001.50001.5000例子14的M代碼具有兩個(gè)輸入?yún)?shù)、三個(gè)輸出參數(shù),所以在使用該函數(shù)的時(shí)候,需要將必要的輸入、輸出參數(shù)寫(xiě)明。注意調(diào)用該函數(shù)時(shí)的語(yǔ)法,將輸出參數(shù)依次寫(xiě)在一個(gè)向量中,若輸出參數(shù)的個(gè)數(shù)與函數(shù)定義的輸出參數(shù)個(gè)數(shù)不一致,則在例子14中,將計(jì)算得到的前幾個(gè)輸出參數(shù)作為返回值,個(gè)數(shù)等于用戶(hù)指定的輸出參數(shù)個(gè)數(shù)。計(jì)算的結(jié)果依次賦值給不同的變量。在使用多個(gè)輸入、輸出參數(shù)的時(shí)候,往往需要判斷用戶(hù)寫(xiě)明的輸入、輸出參數(shù)的個(gè)數(shù),若個(gè)數(shù)與函數(shù)定義不符合的時(shí)候,將給出錯(cuò)誤或者警告信息,這個(gè)時(shí)候,需要使用函數(shù)nargin和nargout來(lái)獲取函數(shù)的輸入、輸出參數(shù)個(gè)數(shù),見(jiàn)例子15。例子15nargin和nargout示例。001 functionc=testarg(a,b)002 %TESTARG檢測(cè)輸入輸出參數(shù)個(gè)數(shù)003 %該函數(shù)根據(jù)不同的輸入輸出參數(shù)個(gè)004 %數(shù)進(jìn)行相應(yīng)的操作005 if(nargout~=1)006 disp('使用該函數(shù)必須指定一個(gè)輸出參數(shù)!');007 return008 end009 switchnargin010 case0011 disp('使用該函數(shù)至少需要一個(gè)輸入?yún)?shù)!');012 c=[];013 return014 case1015 c=a.^2;016 case2017 c=a+b;018 end運(yùn)行例子4-16,在MATLAB命令行窗口中,鍵入下面的指令:>>A=[123];>>B=[235];>>testarg(A,B)使用該函數(shù)必須指定一個(gè)輸出參數(shù)!>>C=testarg使用該函數(shù)至少需要一個(gè)輸入?yún)?shù)!C=[]>>C=testarg(A)C=149>>C=testarg(A,B)C=358>>C=testarg(A,B,C)???Errorusing==>testargToomanyinputarguments.運(yùn)行例子15的代碼時(shí),使用不同的輸入、輸出參數(shù),函數(shù)本身和MATLAB系統(tǒng)將自動(dòng)檢測(cè)參數(shù)的個(gè)數(shù),在最后一次調(diào)用時(shí),由于使用的輸入?yún)?shù)個(gè)數(shù)超過(guò)了函數(shù)定義的個(gè)數(shù),所以MATLAB給出了錯(cuò)誤信息。
MATLAB的M函數(shù)文件還可以具有個(gè)數(shù)不確定的輸入、輸出參數(shù),也就是說(shuō),在定義M函數(shù)文件的時(shí)候,不指明輸入、輸出參數(shù)的個(gè)數(shù),而是在程序中通過(guò)編寫(xiě)程序完成具體參數(shù)的確定,完成該功能主要依靠varargin和varargout函數(shù)。當(dāng)函數(shù)的定義具有以下形式的時(shí)候
functiony=function_name(varargin)函數(shù)function_name可以接受任意個(gè)數(shù)的輸入?yún)?shù);而當(dāng)函數(shù)具有下面的形式時(shí)
functionvarargout=function_name(n)函數(shù)function_name可以輸出任意個(gè)數(shù)的輸出參數(shù)。可以將varargin函數(shù)和varargout函數(shù)結(jié)合在同一個(gè)M文件函數(shù)中使用。例子16
不確定的輸入?yún)?shù)個(gè)數(shù)。001 functiony=varargin_example(varargin)002 %VARARGIN_EXAMPLE不確定輸入?yún)?shù)例子003 str=sprintf('輸入?yún)?shù)的個(gè)數(shù):=%d',length(varargin));004 disp(str);005 y=0;006 %varargin的類(lèi)型007 class(varargin)008 fori=1:length(varargin)009 %varargin為元胞數(shù)組010 if(isnumeric(varargin{i}))011 %將每個(gè)為數(shù)值數(shù)組的輸入?yún)?shù)012 %的第一個(gè)元素累加求和013 y=y+varargin{i}(1);014 end015 end運(yùn)行例子16,在MATLAB命令行中鍵入下面的指令:>>varargin_example輸入?yún)?shù)的個(gè)數(shù):=0ans=cellans=0>>varargin_example('a',[123],3,rand(2,5))輸入?yún)?shù)的個(gè)數(shù):=4ans=cellans=4.0153通過(guò)例子16的運(yùn)行結(jié)果和例子的代碼可以看出varargin函數(shù)的使用方法。它相當(dāng)于在MATLAB的函數(shù)入口處開(kāi)辟了足夠大的空間,用于接受各種用戶(hù)的輸入。在使用這個(gè)函數(shù)的時(shí)候,需要在程序中判別函數(shù)輸入?yún)?shù)的類(lèi)別,并且從元胞數(shù)組中正確提取變量,在MATLAB中將這一過(guò)程稱(chēng)之為unpacking。與之相對(duì)應(yīng)的,將函數(shù)的輸入?yún)?shù)傳遞給varargout函數(shù)被稱(chēng)之為packing,在這一過(guò)程中,需要將所有必要的輸出參數(shù)傳遞給varargout元胞數(shù)組,在傳遞參數(shù)的時(shí)候,還需要注意參數(shù)的順序,在例子17中介紹了這一過(guò)程。例子17
不確定的輸出參數(shù)。001 functionvarargout=varargout_example(varargin)002 %VARARGOUT_EXAMPLE不確定個(gè)數(shù)的輸出參數(shù)003 004 %判斷輸出參數(shù)的個(gè)數(shù)005 %下面注釋行中的代碼執(zhí)行有錯(cuò)誤006 %str=sprintf('輸出參數(shù)的個(gè)數(shù):=%d',length(varargout));007 %必須使用nargout008 str=sprintf('輸出參數(shù)的個(gè)數(shù):=%d',nargout);009 disp(str);010 if(nargout<=nargin)011 fork=1:nargout012 varargout{k}=varargin{nargin-k+1};013 end014 end運(yùn)行例子17的代碼,在MATLAB命令行中,鍵入下面的指令:>>[ab]=varargout_example(1,2,3,4)輸出參數(shù)的個(gè)數(shù):=2a=4b=3例子17的第006行代碼,若將注釋行符號(hào)“%”刪除,則程序運(yùn)行會(huì)出現(xiàn)錯(cuò)誤。在程序中,若需要判斷輸出參數(shù)的個(gè)數(shù)不能使用length函數(shù),而需要使用nargout函數(shù)。另外,在操作輸出參數(shù)時(shí),需要判斷輸出參數(shù)的個(gè)數(shù),根據(jù)輸出參數(shù)的個(gè)數(shù)完成相應(yīng)的操作。在使用不確定的輸入、輸出參數(shù)時(shí),還可以像下面的代碼行一樣使用這兩個(gè)參數(shù):function[out1,out2]=example1(a,b,varargin)function[i,j,varargout]=example2(x1,y1,x2,y2,flag)
若使用varargout和varargin參數(shù),除了必須給定的參數(shù)以外,其余的參數(shù)是任意數(shù)量可變的,具體的操作參閱例子18。例子18可變的輸入、輸出參數(shù)。001 function[x,y,varargout]=vararginout(a,b,c,d,varargin)002 %VARARGINOUT可變的輸入輸出參數(shù)003 str=sprintf('輸入?yún)?shù)的個(gè)數(shù):=%d',nargin);004 disp(str);005 str=sprintf('輸出參數(shù)的個(gè)數(shù):=%d',nargout);006 disp(str);007 if(nargin<=4)008 error('輸入?yún)?shù)必須多于4個(gè)');009 end010 %處理輸入輸出參數(shù)011 x=a+b+c+d;012 y=a-b+c-d;013 if(nargout>2&&nargin>4)014 for(i=1:nargout-2)015 %這里也許會(huì)出錯(cuò),小心!016 varargout{i}=varargin{end-i-1};017 end018 end運(yùn)行例子18的代碼,在MATLAB命令行中,鍵入下面的指令:>>vararginout(1,2,3,4,5)輸入?yún)?shù)的個(gè)數(shù):=5輸出參數(shù)的個(gè)數(shù):=0ans=10>>[a,b,c]=vararginout(1,2,3,4,5,6,7,8)輸入?yún)?shù)的個(gè)數(shù):=8輸出參數(shù)的個(gè)數(shù):=3a=10b=-2c=64.3子函數(shù)和私有函數(shù)同一個(gè)M函數(shù)文件中可以包含多個(gè)函數(shù)。如果在同一個(gè)M函數(shù)文件中包含了多個(gè)函數(shù),那么將出現(xiàn)在文件中的第一個(gè)M函數(shù)稱(chēng)為主函數(shù)(primaryfunction),其余的函數(shù)稱(chēng)為子函數(shù)(subfunction)。M函數(shù)文件的名稱(chēng)一般與主函數(shù)的名稱(chēng)保持一致,其他函數(shù)都必須按照函數(shù)的基本結(jié)構(gòu)來(lái)書(shū)寫(xiě),每一個(gè)函數(shù)的開(kāi)始都是函數(shù)定義行,函數(shù)的結(jié)尾是另一個(gè)函數(shù)的定義行的開(kāi)始或者整個(gè)M文件的結(jié)尾(最后一個(gè)子函數(shù)的結(jié)尾就是文件結(jié)束符)。不過(guò),子函數(shù)不像主函數(shù),一般子函數(shù)沒(méi)有在線(xiàn)幫助,子函數(shù)的作用范圍有限,它只能被那些在定義子函數(shù)的M文件中定義的函數(shù)(包括主函數(shù)和其他子函數(shù))調(diào)用,不能被其他M文件定義的函數(shù)調(diào)用。例子19子函數(shù)應(yīng)用例子。001 function[avg,med]=newstats(u)%主函數(shù)002 %NEWSTATS計(jì)算均值和中間值003 n=length(u);004 avg=mean(u,n); %調(diào)用子函數(shù)005 med=median(u,n); %調(diào)用子函數(shù)006 007 functiona=mean(v,n) %子函數(shù)008 %計(jì)算平均值009 a=sum(v)/n;010011 functionm=median(v,n) %子函數(shù)012 %計(jì)算中間值013 w=sort(v);014 ifrem(n,2)==1015 m=w((n+1)/2);016 else017 m=(w(n/2)+w(n/2+1))/2;018 end運(yùn)行例子19,在MATALB命令行窗口中,鍵入下面的指令:>>x=1:11;>>[mean,mid]=newstats(x)mean=6mid=6在MATLAB中有一類(lèi)函數(shù)被稱(chēng)為私有函數(shù),這類(lèi)函數(shù)被放置在名稱(chēng)為private的子目錄中。每一個(gè)函數(shù)文件都是標(biāo)準(zhǔn)的M語(yǔ)言函數(shù)文件,沒(méi)有特殊的關(guān)鍵字。但是,這些函數(shù)僅能被那些位于private子目錄的上一層目錄中的函數(shù)調(diào)用。例如,假設(shè)在MATLAB的搜索路徑中包含路徑\ProjectA
,那么所有位于\ProjectA\private路徑下的函數(shù),只能在其上一層路徑\ProjectA中的函數(shù)文件中調(diào)用。由于私有函數(shù)作用范圍的特殊性,不同父路徑下的私有函數(shù)可以使用相同的函數(shù)名。由于MATLAB搜索函數(shù)時(shí)優(yōu)先搜索私有函數(shù),所以如果同時(shí)存在私有函數(shù)名func1.m和非私有函數(shù)名func1.m,則私有函數(shù)func1.m被優(yōu)先執(zhí)行。創(chuàng)建私有函數(shù)的方法非常簡(jiǎn)單,只要將那些需要設(shè)置為私有的函數(shù)都拷貝到一個(gè)private子目錄中,則這些函數(shù)就能被那些位于父層目錄中的M函數(shù)調(diào)用了。在表4中總結(jié)了子函數(shù)和私有函數(shù)的區(qū)別。表4私有函數(shù)和子函數(shù)比較例子20
私有函數(shù)的例子。創(chuàng)建一個(gè)新的函數(shù)文件,代碼如下:001 functionx=pmean(v,n)002 %MEAN私有函數(shù)例子003 %將該函數(shù)文件保存在pivae子目錄中,004 %則該函數(shù)僅能在上層目錄的函數(shù)文件005 %中調(diào)用006 disp('私有函數(shù)mean');007 x=sum(v)/n;圖3將pmean.m文件保存在private目錄下接著,修改newstats函數(shù),并將其另存為newstats1.m。001 function[avg,med]=newstats1(u)%主函數(shù)002 %NEWSTATS計(jì)算均值和中間值003 n=length(u);004 avg=mean(u,n); %調(diào)用子函數(shù)005 avg1=pmean(u,n) %調(diào)用私有函數(shù)006 med=median(u,n); %調(diào)用子函數(shù)007 008 functiona=mean(v,n)%子函數(shù)009 %計(jì)算平均值010 disp('子函數(shù)mean');011 a=sum(v)/n;012 ......然后在MATLAB命令行中,執(zhí)行newstats1.m函數(shù):>>newstats1(1:10);子函數(shù)meanavg= 5.5000私有函數(shù)meanavg1= 5.50004.4局部變量和全局變量同C語(yǔ)言類(lèi)似,在M語(yǔ)言函數(shù)中也存在局部變量和全局變量。所謂局部變量,就是那些在M函數(shù)內(nèi)部聲明并使用的變量。這些變量?jī)H能在函數(shù)調(diào)用執(zhí)行期間被使用,一旦函數(shù)結(jié)束運(yùn)行,則這些變量占用的內(nèi)存空間將自動(dòng)被釋放,變量的數(shù)值也就不存在了。這是由于MATLAB的解釋器在解釋執(zhí)行函數(shù)的時(shí)候,為不同的函數(shù)創(chuàng)建不同的工作空間,函數(shù)彼此的工作空間相互獨(dú)立,一旦函數(shù)執(zhí)行完畢,則函數(shù)的工作空間就不存在了。在本章前面的例子中,每個(gè)例子的函數(shù)內(nèi)部聲明使用的變量都是局部變量,所以函數(shù)執(zhí)行完畢后,MATLAB的基本工作空間中沒(méi)有這些變量存在,參見(jiàn)例子4-21。例子21
局部變量的例子。001 functionlocal002 %LOCAL察看局部變量的例子003 x=rand(2,2);004 y=zeros(2,2);005 z='函數(shù)中的變量';006 u={x,y,z};007 disp(z)008 whos
運(yùn)行例子21,在MATLAB命令行中,鍵入下面的指令:>>local函數(shù)中的變量
Name SizeBytesClassu 1x3256cellarrayx 2x232doublearrayy 2x232doublearrayz 1x612chararrayGrandtotalis31elementsusing332bytes>>whos
通過(guò)運(yùn)行l(wèi)ocal函數(shù)可以看到,所有在函數(shù)中創(chuàng)建的變量在函數(shù)運(yùn)行結(jié)束后就不存在了。也就是說(shuō),局部變量的生存周期僅在函數(shù)的活動(dòng)期間內(nèi)。與局部變量相對(duì)應(yīng)的就是全局變量。MATLAB將全局變量保存在特殊的工作空間進(jìn)行統(tǒng)一維護(hù)、管理,而將變量聲明為全局變量的方法就是在使用變量前,用關(guān)鍵字global聲明,例如聲明全局變量gXY:>>globalgXY>>whosName SizeBytesClass
gXY 0x00doublearray(global)Grandtotalis0elementsusing0bytes需要強(qiáng)調(diào)一點(diǎn),MATLAB管理、維護(hù)全局變量和局部變量使用了不同的工作空間,所以使用global關(guān)鍵字創(chuàng)建全局變量的時(shí)候有三種情況:
(1)若聲明為全局的變量在當(dāng)前的工作空間和全局工作空間都不存在,則創(chuàng)建一個(gè)新的變量,然后為這個(gè)變量賦值為空數(shù)組,該變量同時(shí)存在于局部工作空間和全局工作空間。
(2)若聲明為全局的變量已經(jīng)存在于全局工作空間中,則不會(huì)在全局工作空間創(chuàng)建新的變量,其數(shù)值同時(shí)賦值給局部工作空間中的變量。
(3)若聲明為全局的變量存在于局部工作空間中,而全局工作空間不存在,則系統(tǒng)會(huì)提示一個(gè)警告信息,同時(shí)將局部的變量“挪”到全局工作空間中。例子22
全局變量的例子。在MATLAB命令行窗口中,鍵入下面的指令:>>%創(chuàng)建全局變量并賦值>>globalmyx>>myx=10;>>%變量的信息>>whosNameSizeBytesClass
myx1x18doublearray(global)Grandtotalis1elementusing8bytes>>%清除變量>>clearmyx>>%察看信息>>whos>>whosglobalNameSizeBytesClass
myx1x18doublearray(global)Grandtotalis1elementusing8bytes>>%在局部工作空間再次創(chuàng)建變量>>myx=23myx=23>>%變量的信息>>whosNameSizeBytesClass
myx1x18doublearrayGrandtotalis1elementusing8bytes>>%將其修改為全局變量(注意警告信息)>>globalmyxWarning:Thevalueoflocalvariablesmayhavebeenchangedtomatchthe
globals.FutureversionsofMATLABwillrequirethatyoudeclareavariabletobeglobalbeforeyouusethatvariable.>>%看看變量的數(shù)值>>myxmyx=10>>%清除當(dāng)前的工作空間>>clear>>whosglobalNameSizeBytesClass
myx1x18doublearray(global)Grandtotalis1elementusing8bytes>>%清除所有的內(nèi)存空間>>clearall>>whosglobal使用全局變量時(shí),需要小心留意,因?yàn)槿肿兞靠梢栽谌魏蔚暮瘮?shù)中進(jìn)行讀寫(xiě),這樣,可能在比較復(fù)雜的程序中查找全局變量錯(cuò)誤的時(shí)候就非常的麻煩。在MATLAB中還有一類(lèi)變量被聲明為persistent,本書(shū)將其稱(chēng)之為保留變量,這類(lèi)變量類(lèi)似于C語(yǔ)言函數(shù)中被聲明為static類(lèi)型的變量。這類(lèi)變量在函數(shù)退出的時(shí)候不被釋放,當(dāng)函數(shù)再一次被調(diào)用的時(shí)候,這些變量保留上次函數(shù)退出時(shí)的數(shù)值。被聲明為persistent的變量具有以下特征:*變量?jī)H能在聲明變量的函數(shù)內(nèi)使用,其他函數(shù)不能直接使用這些變量。*函數(shù)執(zhí)行退出后,MATLAB不清除這些變量占用的內(nèi)存。*當(dāng)函數(shù)被清除或者重新編輯后,保留的變量被清除。例子23persistent關(guān)鍵字。001 functiony=persistent_example(x)002 %PERSISTENT_EXAMPLE保留變量使用示例003 fori=1:x004 y=myfun;005 end006 007 functiony=myfun008 %子函數(shù)009 %persistent關(guān)鍵字的使用010 persistentcount;011 %count記錄函數(shù)調(diào)用的次數(shù)012 if(isempty(count))013 count=1;014 else015 count=count+1;016 end017 str=sprintf('第%d次調(diào)用該函數(shù)',count);018 disp(str);019 y=count;在MATLAB命令行窗口中,執(zhí)行該函數(shù):>>persistent_example(2)第1次調(diào)用該函數(shù)第2次調(diào)用該函數(shù)ans=2>>persistent_example(3)第3次調(diào)用該函數(shù)第4次調(diào)用該函數(shù)第5次調(diào)用該函數(shù)ans=5從例子23的執(zhí)行情況可以看出變量count記錄了函數(shù)被調(diào)用的次數(shù),如果在MATLAB命令行中鍵入如下指令:>>clearall則所有的變量都會(huì)被清除,此時(shí)再次執(zhí)行例子23:>>persistent_example(3)第1次調(diào)用該函數(shù)第2次調(diào)用該函數(shù)第3次調(diào)用該函數(shù)ans=3count數(shù)值又重新計(jì)數(shù)了。由于使用全局變量有這樣那樣的危險(xiǎn)性,所以建議讀者盡量使用函數(shù)參數(shù)傳遞的方式來(lái)完成函數(shù)之間的數(shù)據(jù)共享,或者可以使用persistent關(guān)鍵字將必要的變量保護(hù)起來(lái)。另外,isglobal
命令可以用來(lái)測(cè)試本地變量與全局工作區(qū)中的變量是否存在聯(lián)系,該命令并不能判斷全局工作區(qū)中是否存在該變量。如果全局工作區(qū)中存在某個(gè)變量,但與本地工作區(qū)中的相應(yīng)變量沒(méi)有聯(lián)系,isglobal函數(shù)返回值為0(假)。5M文件調(diào)試
M語(yǔ)言文件的編輯器——meditor不僅僅是一個(gè)文件編輯器,同時(shí)還是一個(gè)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二四萬(wàn)科物業(yè)應(yīng)急處理合同標(biāo)準(zhǔn)版3篇
- 二零二五版家電行業(yè)電商平臺(tái)合作銷(xiāo)售合同范本2篇
- 2025年度環(huán)保建筑材料代理銷(xiāo)售合同3篇
- 二零二五按揭房產(chǎn)離婚財(cái)產(chǎn)分割協(xié)議范本及子女撫養(yǎng)細(xì)則3篇
- 二零二五年酒店集團(tuán)年度品牌形象合作合同范本3篇
- 二零二四年農(nóng)業(yè)園區(qū)食堂泔水處理與生態(tài)循環(huán)承包合同3篇
- 2025年商業(yè)中心項(xiàng)目PPP合作協(xié)議
- 二零二五版“能源互聯(lián)網(wǎng)”股權(quán)代持合同案例分析3篇
- 個(gè)性化收養(yǎng)協(xié)議規(guī)范格式(2024)版B版
- 事業(yè)單位專(zhuān)屬聘用協(xié)議2024版版B版
- C及C++程序設(shè)計(jì)課件
- 帶狀皰疹護(hù)理查房
- 公路路基路面現(xiàn)場(chǎng)測(cè)試隨機(jī)選點(diǎn)記錄
- 平衡計(jì)分卡-化戰(zhàn)略為行動(dòng)
- 國(guó)家自然科學(xué)基金(NSFC)申請(qǐng)書(shū)樣本
- 幼兒教師干預(yù)幼兒同伴沖突的行為研究 論文
- 湖南省省級(jí)溫室氣體排放清單土地利用變化和林業(yè)部分
- 材料設(shè)備驗(yàn)收管理流程圖
- 培訓(xùn)機(jī)構(gòu)消防安全承諾書(shū)范文(通用5篇)
- (完整版)建筑業(yè)10項(xiàng)新技術(shù)(2017年最新版)
- 第8期監(jiān)理月報(bào)(江蘇版)
評(píng)論
0/150
提交評(píng)論