




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
5.1M文件介紹
5.2程序流程控制
5.3數據輸入/輸出
5.4程序調試與優(yōu)化
5.1.1腳本和函數
1.腳本文件
腳本文件中沒有輸入或輸出參量,因而它是最簡單的M文件類型。當運行一個腳本文件時,MATLAB將逐行執(zhí)行文件內的每條指令。它對工作區(qū)間的數據進行操作,或者創(chuàng)建新的數據并保存到工作區(qū)間,而且在運行結束后數據仍然存在。需要注意的是,腳本的運行有可能覆蓋工作區(qū)間原本需要保留的數據。下面給出一個腳本文件創(chuàng)建和運行的例子。5.1M文件介紹創(chuàng)建一個M文件,輸入如下代碼并保存為plotstems.m:
%AnM-filescript %Commentlines
n=0:20; %Computations
stems1(1,:)=sin(2*pi/21*n);
stems1(2,:)=cos(2*pi/21*n);
stems1(3,:)=exp(-0.2*n);fork=1:3
stem(n,stems1(k,:),'full')%Graphicsoutput
pause
end
在命令窗輸入:
>>plotstems
運行結果如圖5-1所示。圖5-1使用腳本文件繪圖結果
2.函數文件
函數文件是含有輸入和輸出參量的M文件,它在自己的工作區(qū)間(函數工作區(qū)間)內對變量進行操作。函數工作區(qū)間與MATLAB工作空間不同,它只在函數內部傳遞變量而且不會互相覆蓋。
MATLAB的函數文件通常由以下部分組成:
●函數定義行;
●?H1行:幫助文本的第一行,以“%”開始;
●幫助文本;
●注釋;
●函數體。例如,對于一個名為fact.m的計算n階乘的函數文件,其各組成部分描述如下:
functionf=fact(n) 函數定義行
%Computeafactorialvalue.
H1行
%FACT(N)returnsthefactorialofN, 幫助文本
%usuallydenotedbyN!
%Putsimply,FACT(N)isPROD(1:N). 注釋
f=prod(1:n); 函數體如果要計算4!,在命令窗輸入:
>>fact(4)
運行結果:
ans=
245.1.2P代碼文件
對于一個函數或者腳本M文件,可以對其進行預解析,即由M文件創(chuàng)建對應的P代碼文件。例如,使用命令pcodefact對M文件fact.m進行解析,生成偽代碼并保存為fact.p文件。如果同時存在fact.m和fact.p兩個文件,MATLAB則優(yōu)先運行fact.p文件。由于P代碼文件是M文件經過解析的結果,因此它的運行速度要比M文件快。在運行運算量巨大的程序時這種差距尤為顯著,例如大型的圖形用戶界面(GUI)應用。另外,P代碼文件還能夠隱藏程序的算法,這是M文件所不能實現(xiàn)的。5.1.3變量類型
編寫M文件時,所要用到的變量不需要預先定義。變量名必須以字母開頭,其后可以是字母、數字或下劃線。變量名的大小寫是有區(qū)別的,并且不能與函數名或者MATLAB中的關鍵字重名。
MATLAB中有三種變量類型:局部變量、全局變量和持續(xù)變量。
1.局部變量
局部變量存在于MATLAB函數之中,只在它所在的函數內有效(嵌套函數除外),并且與MATLAB工作區(qū)間相互獨立。除了全局變量或持續(xù)變量,一個函數內定義的變量在調用另一個函數時不會在內存中保留,它也不會覆蓋MATLAB工作區(qū)間內的變量。
2.全局變量
全局變量是由global關鍵字定義在MATLAB函數之中,并可以與其他函數或命令共享的變量。例如,在一個名為add3.m的M文件函數內,存在兩個全局變量a、b:
functiony=add3(x)
globalab
y=a+b+x;運行該函數之前,需要對全局變量進行聲明,在命令窗輸入:
>>globalab
>>a=1;
>>b=2;
>>add3(3)
運行結果:
ans=
6
3.持續(xù)變量
持續(xù)變量只能在M文件函數內聲明和使用,由關鍵字persistent來定義。只有聲明了該變量的函數才可以對其進行訪問。如果函數存在,即使MATLAB再調用其他函數,該函數內的持續(xù)變量仍將保留于內存中。例如,在一個名為findSum.m的M文件函數內,存在一個持續(xù)變量SUM_X:
functionfindSum(inputvalue)
persistentSUM_X
ifisempty(SUM_X)
SUM_X=0;
end
SUM_X=SUM_X+inputvalue第一次調用findSum函數時(如findSum(3)),計算得到的SUM_X的值等于函數的輸入參量與原始SUM_X(SUM_X=0)相加之和。
>>findSum(3)
SUM_X=
3
再次調用findSum函數時,由于SUM_X是持續(xù)變量,第一次的計算結果(SUM_X=3)將仍舊存在,故計算得到的SUM_X的值等于函數的輸入參量與現(xiàn)在的SUM_X(SUM_X=3)相加之和。
>>findSum(3)
SUM_X=
6
如此往復,SUM_X的值將反復與輸入參量進行疊加。
>>findSum(3)
SUM_X=
9
…5.1.4關鍵字和特殊值
1.關鍵字
MATLAB中定義了一些關鍵字,在定義變量名時不能與之重名。通過iskeyword命令可以查看MATLAB中定義的所有關鍵字。
>>iskeyword
ans=
‘break’
‘case’
‘catch’
'classdef''continue'
'else'
'elseif'
'end'
'for'
'function'
'global'
'if‘
'otherwise'
‘parfor’
‘persistent’
‘return’
‘switch’
‘try’
‘while’
2.特殊值
MATLAB中定義了一些具有特殊值的變量,如表5-1所示。與關鍵字不同,定義與這些特殊值重名的變量相當于修改這些特殊值。表5-1特殊值5.1.5符號參考
在M文件編程中,經常要用到一些特殊的符號。本小節(jié)將對所有特殊符號(不包括算術、關系和邏輯運算符)進行歸納,作為編程的參考。
1.星號——*
星號通常用在文件操作中,作為文件名或路徑名的通配符,可以代表一個或多個字符。例如,命令dir('Untitled*.m')將羅列所有當前路徑下以Untitled開頭且擴展名為?.m的文件。
2.“猴頭”——@
“猴頭”可以作為構成一般函數或匿名函數句柄的運算符,也可以作為MATLAB類路徑的標志符:
●構成函數句柄,如fhandle=@plot、fhandle=@(x)2*x^2。
●類路徑標志符,如\@myclass\get.m。
3.冒號——:
冒號是產生數值序列的運算符,常用于數組的創(chuàng)建和索引,在第2章中已作過闡述。另外,利用冒號可以將一個數組轉化為列向量。
【例】數組轉化列向量。
在命令窗輸入:
>>A=magic(3),B=A(:)
運行結果:
A=
816
357
492B=
8
3
4
1
5
9
6
7
2
利用冒號還可以在不改變已有數組形狀的前提下對數組進行賦值。
【例】保留數組形狀并賦值。
在命令窗輸入:
>>A=magic(3),A(:)=1:9
運行結果:
A=
816
357
492
A=
147
258
369
4.逗號——,
逗號用于分隔以下幾種類型的元素:
●分隔矩陣的行元素,如A=[3.25,8.32,6.78]。
●分隔數組的索引,如X=A(2,1,3)。
●分隔函數輸入或輸出參量,如function[data,text]=
xlsread(file,sheet,range,mode)。
●分隔一行內的命令或語句并顯示運行結果,如fork=1:3,sum(A(k)),end。
5.大擴號——{}
大括號用于單元數組的創(chuàng)建和索引:
●創(chuàng)建單元數組,如C={[3419],magic(4),‘Cstr’}。
●索引單元數組,如A=C{1,1,2}。
6.單點號——.
單點號可用于結構的字段定義或對象方法的分類符:
●定義結構字段,如funds(2,3).bondtype=‘Corporate’。
●指定對象屬性,如val=asset.current_value。
7.雙點號——..
雙點號用于表示上一級目錄,如當前路徑為F:\matlab\work,命令cd..\bin則設置當前路徑為F:\matlab\bin。
8.省略號——
…
省略號由三個點號構成,是MATLAB中的續(xù)行符。當一行語句過長時,可以在其后加省略號并在下一行續(xù)行書寫。
9.點圓擴號——.()
點圓括號常用于指定動態(tài)結構的字段名。如type=funds(3,2).(fundtype)指定的fundtype就是動態(tài)的字段名。
10.嘆號——!
嘆號用于執(zhí)行需要在MATLAB中執(zhí)行的系統(tǒng)命令,如命令?!regedit將打開系統(tǒng)注冊表。
11.圓擴號——()
圓括號常用于數組的索引(見第2章),或用于指定函數的輸入參數,如functiondydt=odefun(t,y)。
12.百分號——%
百分號主要用于注釋一行程序,有時也用于分類符的轉換,如sprintf('%s=%d',name,value)。
13.百分擴號——%{%}
百分括號用于注釋一段程序,被注釋的段程序以?%{?開頭,以?%}?結束。
14.分號——;
分號用于創(chuàng)建數組、抑制MATLAB輸出或分隔一行內的命令或語句:
●分隔矩陣的行,如A=[3,2;3,1]。
●抑制輸出,即語句末尾存在分號時將不顯示該語句的運行結果。
●分隔一行內的命令或語句,如A=1;B=4,C=3;將只顯示B的結果。
15.單引號——
‘
’
單引號用于創(chuàng)建字符數組,如Str=‘Word’。
16.空格符——
空格符用于分隔以下幾種元素:
●分隔矩陣的行元素,如A=[583]。
●分隔函數的輸入參量,如function[datatext]=xlsread(file,sheet,range,mode)。
17.斜杠與反斜杠——/?\
斜杠或反斜杠用于分隔表示路徑的字符。在Windows系統(tǒng)的路徑表示中,斜杠與反斜杠的作用是相同的;在UNIX系統(tǒng)中,只能用斜杠來表示路徑。
18.中擴號——[]
中括號有以下幾種用途:
●創(chuàng)建數組,如A=[342;245]。
●串接數組,如A=[eye(6),magic(6)]。
●函數的聲明和調用,將返回值包括在中括號內,如[data,text]=xlsread(file,sheet,range,mode)。5.2.1條件控制語句
條件控制語句用于實現(xiàn)根據條件選擇需要執(zhí)行的程序。如果基于一個條件的真或假來選擇執(zhí)行某段程序,則使用if語句;如果要根據多種可能存在的條件來選擇執(zhí)行某段程序,則使用switch語句。
1.if語句
if語句的一般調用格式為
if條件表達式1
語句體15.2程序流程控制
elseif條件表達式2
語句體2
elseif條件表達式3
語句體3
…
else
語句體n
end
如果if或者某個elseif之后的條件表達式為真,則執(zhí)行該if或者elseif之下的語句體;如果if以及所有elseif之后的條件表達式為假,則執(zhí)行else之下的語句體。if語句中,可以沒有elseif條件或者else條件,但是必須有if條件。
【例】
檢測輸入值是否為?-1、0、1。
在命令窗輸入:
>>input=1;
>>ifinput==-1
disp(‘negativeone’);
elseifinput==0
disp(‘zero’);
elseifinput==1
disp(‘positiveone’);
else
disp(‘othervalue’);
end運行結果:
positiveone
2.switch語句
switch語句的一般調用格式為
switch 表達式
case 表達式取值1
語句體1
case 表達式取值2
語句體2
…
otherwise
語句體n
end
當switch后的表達式取值為某個case之后的取值時,程序將執(zhí)行該case之下的語句體。如果找到第一個滿足表達式取值的case,其他的case語句將不再執(zhí)行;如果沒有滿足表達式取值的case,則執(zhí)行otherwise之下的語句體。
【例】
檢測輸入值是否為?-1、0、1。
在命令窗輸入:
>>input=1;
>>switchinput
case-1
disp(‘negativeone’);
case0
disp('zero');case1
disp(‘positiveone’);
otherwise
disp(‘othervalue’);
end
運行結果:
positiveone5.2.2循環(huán)控制語句
循環(huán)控制語句用于重復執(zhí)行某段程序代碼,可用通過循環(huán)條件來控制循環(huán)的次數。MATLAB的循環(huán)控制語句有for語句和while語句。
1.for語句
for語句按照預先指定好的循環(huán)次數執(zhí)行一條語句或語句體,其常用調用格式為
forindex=start1:increment1:end1
語句體
end其中,start1為起始值,increment1為步進值,end1為結束值,循環(huán)次數為1+[(end1-start1)/increment](中括號[]為向零取整運算)。
【例】
計算4!。
在命令窗輸入:
>>x=1;
>>fori=1:1:4
x=x*i;
end
>>x運行結果:
x=
24
此外還有一種for語句格式,以矩陣A的列階數作為循環(huán)次數。
fork=A
語句體
end
2.while語句
如果while語句之后的表達式為真,while語句將始終執(zhí)行,其常用的調用格式為
while 表達式
語句體
end
【例】
計算4!。在命令窗輸入:
>>i=0;
>>x=1;
>>whilei<4
i=i+1;
x=i*x;
end
x運行結果:
x=
24
while語句也可以是關于矩陣或數組的表達式,但在這種情況下當所有元素全部為真時表達式才為真。
3.continue語句
continue語句的作用是結束本次for或while循環(huán)(即跳過循環(huán)體內該語句之后的所有語句),直接進入下一個循環(huán)的執(zhí)行判斷。
【例】顯示magic.m文件行數。
在命令窗輸入:
>>fid=fopen(‘magic.m’,‘r’);
count=0;
while~feof(fid)
line=fgetl(fid);
ifisempty(line)|strncmp(line,'%',1)continue
end
count=count+1;
end
disp(sprintf(‘%dlines’,count));
運行結果:
25lines
4.break語句
break語句的作用是終止for或while循環(huán),即只跳出本層循環(huán),而不跳出外層循環(huán)。
【例】顯示magic.m文件幫助。
在命令窗輸入:
>>fid=fopen(‘magic.m’,‘r’);
s=‘’;
while~feof(fid)
line=fgetl(fid);
ifisempty(line)break
end
s=strvcat(s,line);
end
disp(s)運行結果:
functionM=magic(n)
%MAGICMagicsquare.
%MAGIC(N)isanN-by-Nmatrixconstructedfromtheintegers
%1throughN^2withequalrow,column,anddiagonalsums.
%ProducesvalidmagicsquaresforallN>0exceptN=2.5.2.3錯誤控制語句
錯誤控制語句try-catch-end的作用是在try之下的一個語句出現(xiàn)錯誤時跳出該語句體并執(zhí)行catch語句體,其基本調用格式為
try
語句體1
catch
語句體2
end
使用lasterr函數可以查詢最后的錯誤信息,查詢結果為空字符串時表示語句體1成功執(zhí)行。
【例】錯誤控制判斷。
在命令窗輸入:
>>n=4;
A=eye(3);
try
an=A(n,:),
catch
an=A(end,:),
end
lasterr運行結果:
an=
001
ans=
Indexexceedsmatrixdimensions.5.2.4程序終止語句
程序終止語句return用于終止當前的命令序列并返回正在被調用的函數,也可以用于終止keyboard方式。例如計算行列式的函數det.m中,利用程序終止語句return對于輸入矩陣為空的情況做了如下處理(即令空矩陣的行列式值為1并返回該函數):
functiond=det(A)
%DETdet(A)isthedeterminantofA.
ifisempty(A)
d=1;
return
else
...
end
MATLAB提供了一系列用于文件輸入/輸出(I/O)的底層函數,這些函數是基于ANSI標準C語言I/O函數的。對文件進行底層I/O操作時,一般有以下三個步驟:
(1)打開文件;
(2)讀寫數據;
(3)關閉文件。
本節(jié)將主要介紹MATLAB的文件操作的三個步驟及需要用到的函數。5.3數據輸入/輸出5.3.1打開文件
對文件進行讀寫操作以前必須先打開文件。MATLAB的fopen函數用于打開文件,其調用格式如下:
fid=fopen(‘filename’,‘permission’)
其中參數filename為要打開的文件名,也可以在這個參數中指定文件的路徑信息。permission指定要對文件進行操作的方式,可以為以下任一字符串?!?‘r’:只讀方式。
●?‘w’:只寫方式。該方式將覆寫原有文件內容,若文件不存在,則生成新文件。
●?‘a’:追加方式。保留原有文件內容,在文件尾追加寫入數據。
●?‘r+’:可讀可寫方式。
●?‘w+’:清除文件內容或創(chuàng)建文件用于文件讀寫。
●?'a+':可讀、追加方式。如果文件不存在,則創(chuàng)建該文件?!?‘W’:寫文件,寫的過程中不自動刷新文件內容,當關閉文件時保存所寫數據。
●?‘A’:以追加方式寫文件,過程中不自動刷新文件內容,當關閉文件時保存所寫數據。
通常情況下fopen默認以二進制方式打開文件,可以在permission后加?'b'?來顯式說明。若要以文本的方式打開文件,則給permission后加?'t'。如?'rb'?表示以二進制只讀方式打開文件,'w+t'?表示以文本可讀可寫方式打開文件。在UNIX系統(tǒng)上,文本和二進制方式并無區(qū)別,因此不用考慮加?'b'?加?'t'?的問題。
fid為fopen返回的一個文件標識符(fileidentifier)。fid為1表示標準輸出,為2表示標準錯誤。若文件打開失敗,則fid為-1,并且可以返回一個錯誤消息。下面給出一個打開文件的例子。
【例】
打開文件。在命令窗輸入:
>>fid=0;
whilefid<1
filename=input(‘Openfile:’,‘s’);
[fid,message]=fopen(filename,‘r’);
iffid==-1
disp(message)
end
end命令窗中將顯示:
Openfile:
如果輸入一個不存在的文件nofile.txt:
Openfile:nofile.txt
運行結果:
Nosuchfileordirectory
如果不輸入任何文件名:
Openfile:運行結果:
Cannotopenfile.Existence?Permissions?Memory?...
如果輸入正確的文件名existfile.txt(假設文件existfile.txt存在于當前路徑):
Openfile:existfile.txt
則命令窗內不出現(xiàn)任何消息。5.3.2讀寫操作
1.讀寫二進制文件
fread函數用于讀取二進制文件,其基本調用格式為
A=fread(fid)
其中A為讀取數據返回的矩陣。
【例】讀取二進制文件。創(chuàng)建一個二進制文件char.bin,其內容如下:
TEST
R5Y
在命令窗輸入:
>>fid=fopen(‘char.bin’,‘r’);
A=fread(fid)‘
fclose(fid);運行結果:
A=
846983841310825389
繼續(xù)在命令窗輸入:
>>disp(char(A));
運行結果:
TEST
R5Y
A=fread(fid,SIZE)表示讀取fid所標識的文件,從當前文件指針所指位置開始的前SIZE個字節(jié)。打開文件后,文件指針的位置最初位于文件開始處。其中SIZE可以為以下任意一種格式:
●?N:讀取前N個字節(jié),返回一個列向量。
●?inf:讀至文件尾部。
●?[M,N]:至多讀取M×N個數據到一個M×N的矩陣A中。按列順序將數據讀取到矩陣A中,不足的部分補零。N可以為inf,M不可以為inf。
A=fread(fid,SIZE,PRECISIOSIZE)表示讀取SIZE個PRECISIOSIZE字長的數據到
矩陣A中,其中SIZE為可選參數,PRECISIOSIZE一般為一個表示數據類型的字符串,默認情況下為?‘uint8’。表5-2列出了可以作為PRECISIOSIZE參數的字符串,其中不論
是MATLAB還是相應的C或Fortran語言的數據類型,都可以作為PRECISIOSIZE參數。
表5-3列出的字符串同樣可用,但是在不同平臺上它們的大小會有差異。表5-2通用精度類型表5-3與平臺有關的精度類型默認情況下fread返回的是一個double類型的矩陣,在PRECISIOSIZE參數中可以指定返回矩陣的數據類型:
‘source1=>source2’
該命令表示讀入的源數據格式為source1,返回的目的數據格式為source2。如果source1與source2相同,則該命令可以簡寫為
*source1例如:
‘uint8=>uint8’:以8位整數讀入數據,并將其保存在一個8位整數的矩陣中。
‘*uint8’:上面格式的簡寫形式,等價于?‘uint8=>uint8’。
‘bit4=>int8’:以4位整數讀入數據,并將其保存在一個8位有符號整數矩陣中。每4位整數變成一個8位整數。
'double=>real*4':以double型讀入數據,并將其保存在一個32位浮點數矩陣中。
【例】以特定數據類型讀取二進制文件。
仍以文件char.txt為例,在命令窗輸入:
>>fid=fopen(‘char.bin’,‘r’);
A=fread(fid,‘uint8=>char’)‘
fclose(fid);
運行結果:
A=
TEST
R5Y
fread函數還可以指定在讀取過程中跳躍的字節(jié)數,其調用格式為
A=fread(fid,SIZE,PRECISIOSIZE,SKIP)
其中SIZE為可選參數,SKIP為跳躍的字節(jié)數。
【例】字節(jié)跳躍讀取二進制文件。
在命令窗輸入:
>>fid=fopen(‘char.bin’,‘r’);
A=fread(fid,‘uint8=>char’,1)‘
fclose(fid);運行結果:
A=
TS
RY
使用fwrite函數可將二進制文件寫到文件中,其調用格式如下:
●?count=fwrite(fid,A):將矩陣A中的元素寫入到fid所標識的文件中去。count表示已經成功寫入元素的數目?!?count=fwrite(fid,A,PRECISION):以指定的數據精度PRECISION,將矩陣A中的元素寫入fid所標識的文件中。PRECISION如表5-2所示。
●?count=fwrite(fid,A,PRECISION,SKIP):以指定的數據精度PRECISION,指定的跳躍數SKIP,將矩陣A中的元素寫入到fid所標識的文件中。當PRECISION為?'bitN'?或?'ubitN'時,SKIP為跳躍的位數,其他情況為跳躍的字節(jié)數。
2.讀寫文本文件
fgetl函數和fgets函數常用于文本文件的讀取。
fgetl函數用于返回下一行文本的字符串且不保留換行符,其調用格式為
tline=fgetl(fid)
其中,fid為文件標識符,當成功讀取文件的下一行時,fgetl返回該行字符串到tline;當fgetl讀到文件末尾時,返回?-1;若讀取錯誤,則返回一個空字符串,可以用函數ferror獲取錯誤信息。
【例】利用fgetl函數讀取文件fgetl.m的內容。
在命令窗輸入:
>>fid=fopen(‘fgetl.m’);
while1
tline=fgetl(fid);
if~ischar(tline),break,end
disp(tline)
end
fclose(fid);運行結果:
functiontline=fgetl(fid)
%FGETLReadlinefromfile,discardnewlinecharacter.
%TLINE=FGETL(FID)returnsthenextlineofafileassociatedwithfile
%identifierFIDasaMATLABstring.Thelineterminatoris
NOT
%included.UseFGETStogetthenextlinewiththeline
terminator
%INCLUDED.Ifjustanend-of-fileisencountered,-1is
returned.
%%Ifanerroroccurswhilereadingfromthefile,FGETLreturns
anempty
%string.UseFERRORtodeterminethenatureoftheerror.
%
%MATLABreadscharactersusingtheencodingscheme
associatedwiththe
%file.SeeFOPENformoreinformation.
%
%FGETLisintendedforusewithfilesthatcontainnewline
characters.%Givenafilewithnonewlinecharacters,FGETLmaytakea
longtimeto
%execute.
%
%Example
%fid=fopen('fgetl.m');
%while1
%tline=fgetl(fid);%if~ischar(tline),break,end
%disp(tline)
%end
%fclose(fid);
%
%SeealsoFGETS,FOPEN,FERROR.
%Copyright1984-2005TheMathWorks,Inc.
%$Revision:5.15.4.5$$Date:2005/12/1223:25:45$
%try
[tline,lt]=fgets(fid);
tline=tline(1:end-length(lt));
ifisempty(tline)
tline='';
endcatch
ifnargin~=1
error(nargchk(1,1,nargin,‘struct’))
end
rethrow(lasterror)
end
fgets函數的功能和用法與fgetl函數基本相同,不同的是fgets函數保留換行符。
3.讀寫格式化文本數據
fscanf函數和fprint函數分別用于數據的格式化讀和寫。fscanf的調用格式為
[A,count]=fscanf(fid,FORMAT,SIZE)
該命令用于將fid所標識文件以FORMAT格式讀入到矩陣A中。參數SIZE決定讀取多少數據。SIZE可以為N、inf、[M,N]任一種格式,具體的同fread函數中的SIZE參數。count是一個可選參數,表示成功讀取的數據個數?!?%c:字符格式;
●?%s:字符串格式;
●?%d:有符號十進制整數;
●?%o:有符號八進制數;
●?%x:有符號十六進制數;
●?%u:無符號十進制整數;
●?%e,%f,%g:浮點數。
關于格式符的更多用法可以參見C語言參考手冊。函數fprintf可以將數據格式化寫入到文件中去,其調用格式為
count=fprintf(fid,FORMAT,A,...)
該函數將數據矩陣A以FORMAT格式寫入到fid所標識的文件中去。count表示已經成功寫入的字節(jié)數。FORMAT是格式符,這里的用法基本同fscanf中的FORMAT參數,不過可以在FORMAT中加入字符串或者轉義字符。常見的轉義字符如表5-4所示。表5-4轉義字符下面通過一個例子來說明fprintf函數的用法。
【例】fprintf函數的用法。
創(chuàng)建一個腳本文件,輸入如下代碼并運行:
x=0:.2:1;
y=[x;exp(x)];
fid=fopen(‘exp.txt’,‘wt’);
fprintf(fid,‘x:%6.2f\ty=%12.8f\n’,y);
fclose(fid)在命令窗輸入typeexp.txt命令查看結果:
>>typeexp.txt
x:0.00 y=1.00000000
x:0.20 y=1.22140276
x:0.40 y=1.49182470
x:0.60 y=1.82211880
x:0.80 y=2.22554093
x:1.00 y=2.71828183
4.文件定位
前面提到過文件指針的概念,這里將詳細介紹文件指針是如何在文件內部定位的。當打開文件時,操作系統(tǒng)通過一個文件指針來指示當前文件的位置。這個指針將決定對文件進行操作時,從文件的何處開始進行讀或寫操作。MATLAB提供了函數fseek、ftell,用于實現(xiàn)對文件指針的操作。
fseek函數用于設定文件指針的位置,其調用格式為
status=fseek(fid,OFFSET,ORIGIN)該函數將fid所標識的文件的文件指針,移到以ORIGIN為基點,以OFFSET為偏移量的位置。若操作成功,則status為0,否則status為?-1。
參數ORIGIN為文件指針移動的基點,可以為以下字符串:
●?‘bof’:-1,文件起始位置;
●?‘cof’:0,指針當前位置;
●?'eof':1,文件末尾。
OFFSET為文件的偏移地址,說明如下:
●?OFFSET>0:向文件末尾方向移動文件指針;
●?OFFSET=0:偏移地址為0,將文件指針移動到ORIGIN所指位置;
●?OFFSET<0:向文件起始位置移動文件指針。
例如,fseek(fid,8,'bof')表示從文件的起始位置?'bof'?處向文件末尾方向移動8個字符,結果如圖5-2所示。fseek(fid,0,'eof')表示將文件指針移動到文件末端。圖5-2文件定位示例
ftell函數用于獲取當前文件指針的位置,其調用格式為
position=ftell(fid)
如果position為?-1,則表示查詢當前文件指針位置不成功,可以用ferror獲取錯誤信息。5.3.3關閉文件
fclose函數用于關閉文件,這是執(zhí)行文件操作后必須執(zhí)行的操作,與fopen函數配套使用。前面的很多例子中已經使用過fclose函數,這里主要介紹fclose函數的其他調用格式:
●?status=fclose(fid):當函數返回0時表示成功關閉文件,返回?-1時則表示關閉過程中發(fā)生錯誤。如果fid不標識一個已經打開的文件,或者為0(標準輸入)、1(標準輸出)、2(標準錯誤),則fclose拋出一個異常?!?status=fclose(‘all’):關閉除fid為0、1、2以外的所有文件。成功時返回0,否則返回?-1。
【例】打開文件、文件定位、讀寫二進制文件、關閉文件。
創(chuàng)建文件test1.dat,其內容為
Pine
applesandtea.
Orangutansandmonkeys,
Dragonflysorfleas.創(chuàng)建文件test2.dat,其內容為
Orangesandlemons,
要將text1.dat中第二行以后的數據寫入到text2.dat文件的尾端,在命令窗輸入:
>>fid1=fopen(‘test1.dat’,‘r’);
fseek(fid1,4,‘bof’);
A=fread(fid1,inf,‘uint32’);
fid2=fopen(‘test2.dat’,‘r+’);
fseek(fid2,0,‘eof’);
fwrite(fid2,A,‘uint32’);
fclose('all');要顯示改動后test2.dat文件的內容,在命令窗輸入:
>>typetest2.dat
運行結果:
Orangesandlemons,
applesandtea.
Orangutansandmonkeys,
Dragonflysorfleas.5.3.4更多文件I/O函數
除以上小節(jié)介紹的MATLAB底層文件I/O操作函數之外,在此基礎上,MATLAB針對不同的文件格式,提供了更為豐富的文件I/O函數。這些函數功能更為強大,使用也更方便。表5-5列出了MATLAB支持的可讀寫數據文件格式及相關函數。這些函數的具體使用方法較為簡單,此處不再贅述。表5-5MATLAB支持的可讀寫數據文件格式5.4.1程序的調試
編寫程序的過程中不免出現(xiàn)錯誤,調試錯誤的過程與編寫程序的過程同樣重要,因此掌握一定的調試技巧,對于提高編程效率是大有益處的。
MATLAB程序的錯誤主要有兩類:一類是語法錯誤,比如函數名拼寫錯誤、調用參數不匹配、標點符號丟失、關鍵字不完整等,一般這類錯誤在編譯期間即可被發(fā)現(xiàn)。5.4程序調試與優(yōu)化
MATLAB會給出錯誤警告的內容及相應行。根據錯誤信息就可以很容易地排除和修正這類錯誤。另一類錯誤是運行時錯誤。這類錯誤往往是由于邏輯錯誤而引起的,表現(xiàn)在程序運行結果與預想結果不一致,但編譯器卻無法給出錯誤所在。較語法錯誤來說,運行時錯誤更具隱蔽性,調試難度也較大。本小節(jié)主要針對運行時錯誤來介紹幾種調試的方法。
1.以命令行模式進行M文件調試
用命令行模式調試M文件,不僅快速便捷、功能強大,而且具有較好的通用性,適合于各種不同的平臺。表5-6列出了M文件的常用調試函數。表5-6常用調試函數下面對幾個常用的調試函數進行具體的介紹。
(1)?dbstop函數用于在M文件中設置斷點,其調用格式如下:
●?dbstopinMFILEatLINENO:在M文件MFILE的第LINENO行處設置斷點。這里的LINENO處若為注釋,則斷點設為該段注釋結束后的下一行程序段。
●?dbstopinMFILEatLINENO@N:設置程序在執(zhí)行到MFILE的第LINENO行,第N個匿名函數處停止。
●?dbstopinMFILEatLINENO@NifEXPRESSION:如果EXPRESSION為真,則設置dbstopinMFILEatLINENO@N?!?dbstopiferror:當執(zhí)行M文件遇到錯誤時,停止運行程序到產生錯誤的行,并使程序進入調試狀態(tài)。這里的錯誤不包括try…catch語句中檢測到的錯誤,用戶不能再運行產生錯誤行以后的程序。
●?dbstopifcatcherror:基本同上,不同的是這里包括try…catch語句中檢測到的錯誤。
●?dbstopiferroridentifier:當程序遇到信息為identifier的錯誤時,程序停止在產生錯誤的行,其他同命令dbstopiferror?!?dbstopifwarning:當執(zhí)行M文件遇到警告時,程序暫停在產生錯誤的行并進入調試狀態(tài)。執(zhí)行此命令后可以用dbcont或dbstep恢復執(zhí)行程序。
●?dbstopifnaninf或dbstopifinfnan:當執(zhí)行M文件遇到無窮值或者非數值時,程序暫停并進入調試狀態(tài)。
(2)?dbclear函數用于清除M文件中的斷點,其調用格式如下:
●?dbclearall:清除所有M文件中的斷點。
●?dbclearinMFILE:清除MFILE文件中的所有斷點。
●?dbclearinMFILEatLINENO:清除MFILE文件中第LINETO行的斷點。
●?dbclearinMFILEatLINENO@N:清除MFILE文件第LINENO行,第N個匿名函數中設置的斷點?!?dbclearinMFILEatSUBFUN:清除在MFILE文件子函數SUBFUN中的所有斷點。
●?dbcleariferror:清除由命令dbstopiferror或dbstopiferroridentifier設置的斷點。
●?dbclearifcaughterror:清除由命令dbstopifcaughterror或dbstopifcaughterroridentifier設置的斷點。
●?dbclearifwarning:清除由命令dbstopifwarning或dbstopifwarningidentifier設置的斷點。
●?dbclearifnaninf或dbclearifinfnan:清除由命令dbstopifnaninf或dbstopifinfnan設置的斷點。
(3)?dbcont函數用于從斷點處恢復繼續(xù)執(zhí)行程序,直到遇到下一個斷點或者錯誤,或者程序執(zhí)行完畢返回基本工作區(qū)間,其調用格式為dbcont。
(4)?dbstep函數用于從當前斷點處恢復,步進地執(zhí)行程序,其調用格式如下:
●?dbstep:執(zhí)行當前斷點處的下一行程序。dbstep會忽略當前行所調用函數中的斷點。
●?dbstepNLINES:該命令將執(zhí)行到當前斷點所在行的下NLINES行程序處,若中間程序行有斷點,則執(zhí)行到斷點處?!?dbstepin:執(zhí)行下一行程序,若此行有函數的調用,則進入該函數內部,否則同dbstep。
●?dbstepout:該命令運行完函數的剩余部分,程序停留在離開函數處。
(5)?dbstatus函數用于查看所有斷點的情況,其調用格式如下:
●?dbstatus:列出所有文件中的斷點。
●?dbstatusMFILE:列出MFILE文件中所有的斷點信息。●?s=dbstatus:該表達式以一個M×1的結構形式返回所有斷點信息,各字段信息如下:
■?name:文件名。
■?file:包含有斷點的文件的路徑。
■?line:斷點行號向量。
■?anonymous:在line字段中的行號向量對應的匿名函數序列向量。如某斷點行有第2個匿名函數,則其對應的匿名函數序列為2?!?expression:與line中行對應的斷點條件表達式字符串向量。
■?cond:條件字符串,如?‘error’,‘caughterror’,‘warning’
或?‘naninf’。
■?identifier:當cond是?'error','caughterror'?或者?'warning'?時,該字段為信息類別字符串向量。
(6)?dbtype函數用于顯示帶有行號的M文件內容,其調用格式如下:
●?dbtypeMFILE:顯示指定文件MFILE的內容并帶有行號信息。
●?dbtypeMFILEstart:end:顯示指定文件MFILE從start到end行之間的內容并帶有行號信息。
(7)?dbstack函數用于顯示當前斷點所在的M文件名和產生斷點的行號,并且以執(zhí)行順序列出,其調用格式如下:
●?dbstack:顯示函數調用堆棧中的文件名及行號信息。●?dbstack(N):省略堆棧前N個函數的調用信息。
●?dbstack(‘-completenames’):顯示堆棧中函數文件的路徑、文件名與行號。
●?[ST,I]=dbstack:執(zhí)行此命令后,其中ST以一個M×1的結構體形式返回堆棧信息。各字段信息如下:
■?file:出現(xiàn)函數的文件名,如果沒有文件,則這個字段為空。
■?name:文件中的函數名。
■?line:函數行號。
I為返回的當前工作區(qū)間索引。
【例】dbstack的使用。
在調式模式下,如果輸入:
K>>dbstack
運行結果:
Incollatzplotat6
>Intestat1如果輸入:
K>>dbstack(1)
運行結果:
>Intestat1
如果輸入:
K>>dbstack(‘-completenames’)
運行結果:
InF:\Matlab\work\collatzplot.m>collatzplotat6
>InF:\Matlab\work\test.m>testat1如果輸入:
K>>[ST,I]=dbstack
運行結果:
ST=
file:‘collatz.m’
name:‘collatz’
line:6
I=1
(8)?dbquit函數用于退出調試模式,其調用格式如下:
●?dbquit:退出調試模式,所有斷點仍有效。如果調試文件1并跳轉到文件2,執(zhí)行該命令將終止文件1和文件2的調試狀態(tài)。如果在調試文件1的同時也在調試文件2,則運行一次dbquit只能將其中之一退出調試模式。
●?dbquit(‘all’)或dbquitall:一次性終止所有文件的調試狀態(tài)。
2.以GUI方式調試M文件
用戶可以選擇用GUI方式進行M文件的調試,這種方式更加直觀和方便。新建一個M文件,在編譯器主菜單Debug選項的下拉菜單中可以看到如圖5-3所示的各種調試命令。圖5-3GUI方式調試主菜單的部分調試命令在調試工具欄中也有相對應的圖標,如圖5-4所示。
下面將對這些命令作簡要的介紹。
●?Step:單步執(zhí)行。對應工具欄上的按鈕圖標,快捷鍵為F10,對應的調試命令為dbstep。
●?Stepin:單步執(zhí)行,遇到函數則跳轉到函數內部。對應工具欄上的按鈕圖標,快捷鍵為F11,對應的調試命令為dbstepin。圖5-4調試工具欄●?Stepout:跳出函數內部。對應工具欄上的按鈕圖標,快捷鍵為Shift+F11,對應的調試命令為dbstepout。
●?Continue:繼續(xù)執(zhí)行。對應工具欄上的按鈕圖標,快捷鍵為F5,對應的調試命令為dbcont。
●?GoUntilCursor:運行程序直到光標所在的行?!?Set/ClearBreakpoint:設置或清除斷點。對應工具欄上的按鈕圖標,快捷鍵為F12,對應的調試命令為dbstop/dbclear。
●?Set/ModifyConditionalBreakpoint…:設置或修改當前光標所在行的條件斷點。單擊此命令會彈出如圖5-5所示的對話框,在文字框中可輸入條件表達式。同調試命令dbstopinMFILEatLINENOifEXPRESSION,其中LINENO即光標所在行,EXPRESSION即條件表達式。圖5-5MATLABEditor對話框●?Enable/DisableBreakpoint:使斷點有效/失效。
●??ClearBreakpointsinAllFiles:對應工具欄上的按鈕
圖標,對應的調試命令為dbclearall。
●?StopifError/Warnings…:單擊該菜單項會彈出如圖5-6所示的對話框,相應的調試命令在相應選項后面的括號中均有注明。圖5-6StopifError/WarningsforAllFiles對話框●
ExitDebugMode:對應工具欄上的按鈕圖標,快捷鍵為Shift+F5,對應的調試命令為dbquit。
●在工具欄的左端還有一個下拉列表框。當程序處于調試狀態(tài)時該框被激活。這個下拉列表框中顯示了函數的調用關系,對應于調試命令中的dbstack。
3.調試輔助函數
前面介紹了通過命令調試程序以及通過GUI調試程序的方法。另外MATLAB還提供了一些調試輔助函數,可以幫助用戶更快地發(fā)現(xiàn)問題的所在。調試輔助函數的功能描述如表5-7所示。表5-7調試輔助函數5.4.2程序的優(yōu)化
本小節(jié)將介紹如何利用優(yōu)化工具分析和改進程序的性能,以及如何編寫性能較高的MATLAB程序語言。
1.使用M-LintCodeCheckReport工具
M-LintCodeCheckReport(代碼檢查報告)工具可用于檢查代碼中可能存在的錯誤和問題,并且會向用戶提出改進代碼的建議。在當前路徑窗口中單擊按鈕,將打開M-LintCodeCheckReport窗口,窗口中顯示的是當前路徑下所有M文件的代碼分析結果。單擊文件名超鏈接可以打開文件,單擊文件行號超鏈接可以打開文件并定位到檢查存在問題的代碼行,如圖5-7所示。圖5-7M-LintCodeCheckReport窗口如果對文件進行了改動,保存改動后單擊RerunThisReport,可以更新顯示改動后的分析報告。
下面給出了獲取M-Lint信息的其他方法,通過這些方法同樣可以得到M-Lint信息,只是信息的形式不同:
●在M文件編輯/調試器界面的主菜單中選擇Tools>M-Lint>ShowM-LintReport來訪問M-Lint代碼分析報告。
●使用mlint函數分析指定文件并在命令窗內顯示信息,或使用mlintrpt運行mlint并以Web瀏覽器方式顯示M-Lint代碼分析報告。
●使用自動M-Lint代碼分析校正,可以在編寫代碼的過程中不停地對代碼進行檢查。
2.使用Profiler進行優(yōu)化
MATLAB提供的M文件Profiler可以用于實現(xiàn)程序性能的優(yōu)化。Profiler是一個基于profiler函數返回結果的GUI。Profiler可以幫助用戶決定如何修改代碼以提高程序的性能。
Profiling是一種測量程序耗費時間的方法。使用MATLABProfiler可以確定代碼中最耗費時間的函數,從而決定是否要調用這些函數或者盡可能地減少調用。這在決定一個特定函數調用次數是否合理時十分有用。由于程序通常有很多層,而代碼不能夠明確地調用最耗時間的函數。程序代碼中的函數可能調用了其他耗費時間的函數,因此決定調用哪個函數非常重要。通過profiling可以分析程序性能,并且可以對程序進行以下優(yōu)化:
●避免因疏忽帶來的不必要的計算。
●改變算法以避免耗費大量時間的函數。
●存儲結果,避免下次調用時重復計算。用戶可以通過以下方法中的任意一種來打開Profiler:
●在MATLAB桌面主菜單上選擇Desktop>Profiler。
●在MATLAB桌面工具欄上單擊Profiler按鈕。
●對于一個MATLAB編輯/調試器中的文件,選擇Tools>OpenProfiler。
●選中歷史命令窗口中的一條或多條語句,在右鍵菜單上選擇ProfileCode。
●在命令窗輸入命令:profileviewer。
使用命令profileviewer打開Profiler,如圖5-8所示。圖5-8Profiler瀏覽器接下來可以按照以下步驟運行profiling:
(1)在Profiler的Runthiscode字段輸入將要運行的語句或文件名。
(2)單擊StartProfiling或者在語句輸入完畢時按回車鍵,啟動profiling。
【例】使用Profiler。
打開Profiler,在Runthiscode字段輸入如下語句:
[t,y]=ode23(‘lotka’,[0100],[20;20])
單擊StartProfiling,運行結果如圖5-9所示。圖5-9使用Profiler分析代碼圖5-9所示的ProfileSummary報告中顯示了所有函數執(zhí)行統(tǒng)計以及每個被調用函數的統(tǒng)計:
●?FunctionName:調用到的函數或子函數列表。第一次顯示時,這些函數將按它們耗費時間的多少從大到小排列。單擊FunctionName超鏈接后,可以將函數按字母表順序
排列。
●?Calls:函數被調用的次數。單擊Calls超鏈接后則按它們被調用次數的多少從大到小排列。●?TotalTime:每個函數總共耗費的時間,包含所有被調用的子函數。單擊TotalTime超鏈接后可以按它們耗費時間的多少從大到小排列。
●?SelfTime:每個函數總共耗費的時間,不包含所有被調用的子函數。單擊SelfTime超鏈接后可以按它們耗費時間的多少從大到小排
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 兒保門診小兒骨密度檢測結果分析及干預
- 駕校崗位聘用合同(2篇)
- 高校合同的范本(2篇)
- 風險評估協(xié)議書(2篇)
- 橫店旅游景點
- 豬場生物安全工作述職報告
- 動漫游戲創(chuàng)新創(chuàng)業(yè)
- 自閉癥療愈師培訓
- 節(jié)前保密教育培訓
- 倉儲部經理個人述職報告
- 秦漢時期建筑
- 東成28電錘使用說明書
- 2022-2023學年山東省煙臺市海陽市八年級(下)期末語文試卷(五四學制)
- 六年級1班語文老師家長會課件
- 哲學與人生課件
- APIC 基于風險的數據完整性管理實踐指南-2019(中英文對照版)
- 港澳臺專題教育課件
- 環(huán)縣聲環(huán)境功能區(qū)劃技術報告(2018-2022)
- 高中英語外研版高中必修2Module3Music-Music教案
- 車間主要生產設備一覽表
- 五年級下冊數學蘇教版課件 因數和倍數的認識
評論
0/150
提交評論