delphi基本语法
//delphi中exit,abort,break,continue 的區(qū)別
exit: 退出函數(shù)體
abort: 遇到異常,安靜處理,就是不顯示不提示
break: 退出當(dāng)前循環(huán)體,包括for ,while, repeat等循環(huán)體
continue: 結(jié)束循環(huán)內(nèi)的本次處理,繼續(xù)從循環(huán)體的開始位置繼續(xù)執(zhí)行
Exit 是跳出當(dāng)前代碼塊,也就是當(dāng)前函數(shù),跳出后是要繼續(xù)向下執(zhí)行的(如果有后續(xù)代碼)。
Abort 是從 EAbort 過來的,可以激發(fā) exception,其實(shí)質(zhì)就是 Abort = RaiseException(),是一個不出現(xiàn)對話框的異常。所以 Abort 的行為和異常是一樣的,其代碼執(zhí)行順序也是follow異常的流程。
例如:
try
(1) //執(zhí)行了
abort;
(2) //不執(zhí)行
exception
(3) //執(zhí)行了
end;
用 Abort 能夠執(zhí)行 exception 里邊的代碼,但是如果用 Exit,就直接離開,不管 exception。
例如:
procedure p1;
begin
p2;
p3;
end;
procedure p2;
begin
abort; //exit;
end;
procedure p3;
begin
//showmessage()..
end;
******************************************************************************
在Delphi過程、函數(shù)中傳遞參數(shù)幾個修飾符為Const、Var、Out。另一種不加修飾符的為默認(rèn)按值傳遞參數(shù)。
一、默認(rèn)方式以值方式傳遞參數(shù)
procedure TForm1.ProcNormal(Value: string);
begin
OrigNum:=Value+' Me';
lblReturn.Caption:=OrigNum;//OrigNum為'Hello Me'
lblOrig.Caption:=Value;//Value為'Hello'
end;
調(diào)用:
OrigNum:='Hello';
ProcNormal(OrigNum);
二、以Const方式傳遞參數(shù),這個參數(shù)在調(diào)用過程中不能改變,并且這種方式會被編譯器優(yōu)化,一般建議盡可能地使用這種方式。
procedure TForm1.ProcConst(const Value: string);
begin
OrigNum:=Value+' Me';
lblReturn.Caption:=OrigNum;//為'Hello Me‘
lblOrig.Caption:=Value;//為'Hello Me'
end;
三、按引用方式傳遞參數(shù)
procedure TForm1.ProcRef(var value: string);
begin
OrigNum:=Value+' Me';
lblReturn.Caption:=OrigNum;//為'Hello Me‘
lblOrig.Caption:=Value;//為'Hello Me'
end;
四、按Out方式傳遞參數(shù),這個方式傳遞參數(shù)時,參數(shù)可以不被初始化,即使有值也被忽視,它一般用于輸出,它可以實(shí)現(xiàn)在一個過程中返回多個值,我們通常在分布式對象模型,如COM中使用它。
procedure TForm1.ProcOut(out Value: string);
begin
OrigNum:=Value+' Me';
lblReturn.Caption:=OrigNum;//為'Me'
lblOrig.Caption:=Value;//為'Me'
end;
五、無類型參數(shù),這是一種較為特殊的方法,參數(shù)的類型不確定,只能用Const、Var、Out修飾,不能用于值方式傳遞參數(shù),具體使用示例如下:
procedure TForm1.ProcUntype(const Value);
begin
OrigNum:=string(Value)+' Me';
lblReturn.Caption:=OrigNum;//為'Hello Me'
lblOrig.Caption:=string(Value);//為'Hello Me'
end;
六、默認(rèn)參數(shù),即如果此參數(shù)在調(diào)用時未提供時,將使用默認(rèn)值。
procedure TForm1.ProcDefault(const Value, constDefaultValue:string=' 123');
begin
OrigNum:=Value+' Me'+DefaultValue;
lblReturn.Caption:=OrigNum;//為'Hello Me 123'
lblOrig.Caption:=Value;// 為'Hello Me 123'
end;
七、開放數(shù)組參數(shù),即參數(shù)數(shù)組的元素個數(shù)不確定。
procedure TForm1.ProcArray(const Value: array of string);
var
i:Integer;
begin
for i:=Low(Value) to High(Value) do
OrigNum:=OrigNum+Value[i];//調(diào)用后為'Hello abc dbd'
lblReturn.Caption:=OrigNum;
end;
調(diào)用:
OrigNum:='Hello';
ProcArray([' abc ',' dbd']);
八、無類型開放數(shù)組參數(shù),即類型及元素個數(shù)皆不確定。在WIN32平臺中,這個參數(shù)的類型實(shí)際為array ofTVarRec,其使用示例如下:
procedure TForm1.ProcArrayConst(const Value: array of const);
var
i:Integer;
begin
for i:=Low(Value) to High(Value) do
with Value[i] do
case VType of
vtAnsiString: OrigNum:= OrigNum+String(VAnsiString);
vtInteger: OrigNum:=OrigNum+IntToStr(VInteger);
vtBoolean: OrigNum := OrigNum + BoolToStr(VBoolean);
vtChar: OrigNum := OrigNum + VChar;
vtExtended: OrigNum := OrigNum + FloatToStr(VExtended^);
vtString: OrigNum := OrigNum + VString^;
vtPChar: OrigNum := OrigNum + VPChar;
vtObject: OrigNum := OrigNum + VObject.ClassName;
vtClass: OrigNum := OrigNum + VClass.ClassName;
vtCurrency: OrigNum := OrigNum + CurrToStr(VCurrency^);
vtVariant: OrigNum := OrigNum + string(VVariant^);
vtInt64: OrigNum := OrigNum + IntToStr(VInt64^);
end;
lblReturn.Caption:=OrigNum;//調(diào)用后為'Hello abc 3'
end;
調(diào)用:
OrigNum:='Hello';
ProcArrayConst([' abc ',3]);
以上就是常見幾種傳遞參數(shù)的方式。
//另一篇文章關(guān)于delphi參數(shù)傳遞的//
delphi參數(shù)傳遞
參數(shù)傳遞
??聲明/實(shí)現(xiàn)一個過程使用的參數(shù)稱為形式參數(shù)(簡稱形參),調(diào)用過程時傳入的參數(shù)稱為實(shí)際參數(shù)(簡稱實(shí)參)。
{ Info是形參}
procedure ShowInfo(Info: String);
begin
?ShowMessage(Info);
end;
var
?S: String;
begin
?S := 'lxpbuaa';
?{S是實(shí)參}
?ShowInfo(S);
end;
參數(shù)傳遞分兩種:按值(by val)和引用(by ref)。這兩種方式的本質(zhì)區(qū)別是:
按值傳遞時,形參和實(shí)參是兩個變量,它們開始時的值是相同的,即實(shí)參的數(shù)據(jù)被拷貝一份傳遞給了形參。所以此時,形參的改變不會影響到實(shí)參。
引用傳遞時,形參和實(shí)參是同一個變量,可以將它們之一看做是另一個的別名。 所以此時,形參改變時,實(shí)參跟著改變。
默認(rèn)情況下,參數(shù)是按值傳遞的,傳遞的是數(shù)據(jù)拷貝;如果加了var前綴,則成了引用傳遞。
我們看如下例子:
procedure TForm1.ByVal(I: Integer); ??{按值傳遞I}
begin
?ShowMessage(IntToStr(Integer(@I))); ??
?{取得形參所在地址。你會發(fā)現(xiàn)它和實(shí)參地址是不同的,因?yàn)榇藭r實(shí)參和形參是不同的兩個變量}
?I := I + 1;
end;
procedure TForm1.ByRef(var I: Integer); {引用傳遞I}
begin
?ShowMessage(IntToStr(Integer(@I))); ??
?{取得形參所在地址。你會發(fā)現(xiàn)它和實(shí)參地址是相同的,因?yàn)榇藭r實(shí)參和形參是同一個變量}
?I := I + 1;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
?I: Integer;
begin
?I := 1;
?ShowMessage(IntToStr(Integer(@I))); ????{取得實(shí)參所在地址}
?ByVal(I); ?{ I =1}
?Showmessage(i); {i:=1;實(shí)參沒有變}
?ByRef(I); ?{ I =2}
?showmessage(i); {i:=2,實(shí)參改變了}
end;
按值傳遞的參數(shù)可以指定默認(rèn)值,比如上面的ByVal可以是這樣:
procedure ByVal(I: Integer = 0);
調(diào)用它時可以省掉有默認(rèn)值的參數(shù):ByVal。帶默認(rèn)值的參數(shù)必須位于參數(shù)列表的最后,如:
procedure ByVal(I: Integer = 0; B: Boolean);
是不行的,應(yīng)該改為:
procedure ByVal(B: Boolean; I: Integer = 0);
因?yàn)槟J(rèn)值必須是一個常數(shù)表達(dá)式,所以dynamic-array、procedural、class、class-reference和 interface等參數(shù)只能指定nil默認(rèn)值;而record、variant、file和static-array等類型的參數(shù)則根本不能指定默認(rèn) 值。
如果按值傳遞一個指針類型的參數(shù),情況會變得復(fù)雜而又很有意思。此時,實(shí)際傳遞的是什么呢?是實(shí)際數(shù)據(jù)的拷貝嗎?不,是指針的拷貝,也就是說形參和實(shí)參是 兩個指針,不過這兩個指針指向了相同地址。所以這時候,形參和實(shí)參可以共享它們指向地址中的數(shù)據(jù),但如果改變了形參的指針指向,實(shí)參的指針指向不能跟著改 變。那么總結(jié)一下,就是:按值傳遞指針參數(shù)時,實(shí)參和形參可以共享指針指向地址中的數(shù)據(jù),但是不能共享指針本身的指向。而引用傳遞時,因?yàn)閷?shí)參和形參是同 一個變量,因此實(shí)現(xiàn)完全共享??聪旅娴睦?#xff1a;
procedure TForm1.ByVal(Obj: TObject);
begin
?Obj := Button1; ??
?{改變形參指針指向,實(shí)參的指針指向不會跟著改變,因?yàn)樗鼈兪莾蓚€變量。如果僅僅是改變Obj的屬性而不改變指向,則實(shí)參的屬性會跟著改變}
end;
procedure TForm1.ByRef(var Obj: TObject);
begin
?Obj := Button1; ????
?{改變形參指針指向,實(shí)參的指針指向跟著改變,因?yàn)樗鼈兪峭粋€變量}
end;
procedure TForm1.Button1Click(Sender: TObject);
var
?Obj: TObject;
begin
?Obj := Self; ??????
?{Self即Form1,所以此時實(shí)參Obj的類名(ClassName)是"TForm1"}
?ByVal(Obj); ??????????{按值傳遞指針變量Obj}
?ShowMessage(Obj.ClassName); ??{顯示類名"TForm1"}
?ByRef(Obj); ???????????{引用傳遞指針變量Obj}
?ShowMessage(Obj.ClassName); ??{顯示類名"TButton1"}
end;
上面講了這么多,最根本的還是一句話:按值傳遞時,形參和實(shí)參是兩個變量;引用傳遞時,形參和實(shí)參是同一個變量。抓住這句話,就等于抓住了一切。(ps:關(guān)鍵總結(jié)):
相信你還看到過如下格式的參數(shù)聲明:
function CompareStr(const S1, S2: string): Integer;
function TryStrToInt(const S: string; out Value: Integer): Boolean;
其中使用了const和out關(guān)鍵字。如果你沒有看到過這樣的聲明,也不要緊,它們是真實(shí)存在的。
const聲明的參數(shù)是按值傳遞的,而且形參不能被改變。
out聲明的參數(shù)是引用傳遞的,主要用于定義輸出參數(shù),也就是說不需要輸入值(即實(shí)參不需要初始化),實(shí)參傳遞給形參的值被忽略。
如果用const修飾指針參數(shù),那么只能通過形參修改指針地址里的數(shù)據(jù)而不能修改指針本身的指向。例如對于一個const對象參數(shù),可以修改其屬性,但是不能將它指向其他對象。例如:
procedure ShowInfo(const Form: TForm);
begin
?{以下一句不能通過,編譯器提示:[Error] Unit1.pas(28): Left side ?cannot be assigned to}
?{Form := Form1;}
?{但是通過其屬性或者方法修改隸屬于Form的數(shù)據(jù)}
?Form.Caption := 'lxpbuaa';
?ShowMessage(Form.Caption);
end;
在本小節(jié)的最后,還不得不提及一種很特殊的參數(shù)類型:無類型參數(shù)(Untyped parameters)。
聲明時沒有指定數(shù)據(jù)類型的參數(shù)稱為無類型參數(shù)。因此,從語法上講,無類型參數(shù)可以接收任何類型的數(shù)據(jù)。
無類型參數(shù)必須加const、out或var前綴;無類型參數(shù)不能指定默認(rèn)值。
如以下一些Delphi定義的過程都使用了無類型參數(shù):
procedure SetLength(var S; NewLength: Integer); ???{參數(shù)S}
procedure Move(const Source;var Dest;Count:Integer); ?{參數(shù)Source、Dest}
procedure TStream.WriteBuffer(const Buffer; Count: Longint);{參數(shù)Buffer}
所謂無類型參數(shù)可以接收任何類型的值,只是從語法角度而言的?;蛘哒f,理論上我們可以實(shí)現(xiàn)一個可以使用任何類型變量作為參數(shù)的過程,但是實(shí)際上沒有必要,也不可能做到。
打個比方說,我們想造一輛可以裝載任何物體的汽車。因?yàn)槭恰叭魏挝矬w”,所以物體可能是任何形狀,于是這輛車必須沒有車篷,除了在幾個車輪上鋪一個足夠大 (足夠大就已經(jīng)是個大問題了)的平板外,不能再有任何東西。這時候,這個平板就可以看做是無類型的,因?yàn)樗厦婵梢宰?、擺一張桌子,也可以趕一些動物上 去站著或者躺著。盡管它可以承載很多種類的東西,但是也是有限制的,比如不能放一座山、也無法容納1萬頭豬。所以無類型參數(shù)的類型往往是有一定限制的。比 如SetLength的參數(shù)S只能是字符串、動態(tài)數(shù)組等。
這種限制一般是在過程的實(shí)現(xiàn)中完成的,在運(yùn)行時檢查參數(shù)值的實(shí)際類型。對于與開發(fā)環(huán)境關(guān)系緊密的參數(shù),限制也可以構(gòu)筑在編譯器里。
使用無類型參數(shù)的原因是無法在聲明時使用一個統(tǒng)一的類型來描述運(yùn)行時可能的類型,如SetLength的參數(shù)S可以是字符串和動態(tài)數(shù)組,而并沒有一個統(tǒng)一 的類型來代表字符串和動態(tài)數(shù)組類型,所以干脆聲明為無類型。而將類型限制放到別的地方實(shí)現(xiàn)(如編譯器)。例如SetLength的限制規(guī)則是寫在編譯器中 的,它只能作用于長字符串或者動態(tài)數(shù)組。你企圖完成下面的功能時:
var
?I: Integer;
begin
?SetLength(I, 10);
end;
編譯器編譯時將給出錯誤信息:[Error] Unit1.pas(35): Incompatible types。導(dǎo)致編譯中斷。
小結(jié)
本小節(jié)的內(nèi)容比較重要,重點(diǎn)是理解參數(shù)按值傳遞和引用傳遞的本質(zhì):按值傳遞時,形參和實(shí)參是兩個變量;引用傳遞時,形參和實(shí)參是同一個變量。
聲明指令
聲明一個過程,可以使用register、pascal、cdecl、stdcall和safecall指令來指定參數(shù)傳遞順序和參數(shù)內(nèi)存管理方式,從而影響過程的運(yùn)作。如:
function MyFunction(X, Y: Integer): Integer; cdecl;
這五個指令具有不同含義,如表3-1所示。
表3-1 ?五個指令的不同含義
?
?指令 ??參數(shù)存放位置 ???參數(shù)傳遞順序 ?參數(shù)內(nèi)存管理 ????適用地點(diǎn)
?register ?CPU寄存器 ???從左到右 ???被調(diào)用者 ?默認(rèn).published屬性存取 ?????????????????????????????????方法 必須使用
?pascal ????棧 ?????從左到右 ???被調(diào)用者 ??向后兼容,不再使用
?cdecl ?????棧 ?????從右到左 ???調(diào)用者 ???調(diào)用C/C++共享庫
?stdcall ????棧 ?????從右到左 ???被調(diào)用者 ??API調(diào)用,如回調(diào)函數(shù)
?safecall ????棧 ?????從右到左 ???被調(diào)用者 ??API調(diào)用,如回調(diào)函數(shù)。雙
在一些源代碼(包括Delphi自帶的VCL源代碼)中,你還可能看到near、far、export以及inline、assemble等指令,它們是 為了和16位Windows系統(tǒng)或者早期Pascal/Delphi兼容,在目前的Delphi版本中,已經(jīng)不具有任何意義,所以在新的開發(fā)中不要再使 用。
轉(zhuǎn)載于:https://blog.51cto.com/right2pearl/1567432
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的delphi基本语法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解读设计模式----命令模式(Comma
- 下一篇: 转:靠谱的代码和DRY