Delphi 函數參數機制豐富,支援值參數、變數參數、常數參數、輸出參數、非強類型參數、開放陣列參數、變體開放陣列與預設參數等多種模式。本文系統整理各類參數的語法、語義、效能差異與最佳實踐,附完整代碼範例。
function Power(X: Real; Y: Integer): Real;
// 多參數簡寫
function Test(X, Y: Real): Boolean;
// 混合模式
procedure Demo(var S: string; X: Integer);
procedure WinAPI(HWnd: Integer; Text, Caption: PChar; Flags: Integer);
procedure Untyped(const P; I: Integer); // 非強類型
function DoubleByValue(X: Integer): Integer; // 值參數:複製副本
begin
X := X * 2;
Result := X;
end;
function DoubleByRef(var X: Integer): Integer; // 變數參數:傳址
begin
X := X * 2;
Result := X;
end;
var
I, J, V, W: Integer;
begin
I := 4; V := 4;
J := DoubleByValue(I); // J=8, I=4 (原值不變)
W := DoubleByRef(V); // W=8, V=8 (原值被修改)
end;
| 特性 | 值參數 | 變數參數 |
|---|---|---|
| 關鍵字 | (無) | var |
| 傳遞機制 | 複製資料(大結構體有開銷) | 傳遞位址(固定 4/8 位元組) |
| 可修改原變數 | 否 | 是 |
| 可傳常數/運算式 | 是 | 否(必須為左值) |
function CompareStr(const S1, S2: string): Integer;
var)但禁止寫入,避免複製開銷。const。procedure GetInfo(out Info: TSomeRecord);
var
Rec: TSomeRecord;
begin
GetInfo(Rec); // 調用後 Rec 包含結果
end;
var 提升語義清晰度。function Equal(var Source, Dest; Size: Integer): Boolean;
type
TBytes = array[0..MaxInt - 1] of Byte;
var
N: Integer;
begin
N := 0;
while (N < Size) and (TBytes(Dest)[N] = TBytes(Source)[N]) do
Inc(N);
Result := N = Size;
end;
// 調用示例
type
TVector = array[1..10] of Integer;
TPoint = record X, Y: Integer end;
var
Vec1, Vec2: TVector;
P: TPoint;
begin
Equal(Vec1, Vec2, SizeOf(TVector));
Equal(Vec1[1], Vec1[6], SizeOf(Integer) * 5);
Equal(Vec1[1], P, 4); // 比較 Vec1[1] 與 P.X、Vec1[2] 與 P.Y
end;
注意:編譯器不做類型檢查,完全由開發者保證記憶體佈局相容,屬進階/底層用法。
// 錯誤:短字串長度屬類型一部分,不可直接作參數
procedure Check(S: string[20]); // syntax error
// 正確:定義類型別名
type
TString20 = string[20];
procedure Check(S: TString20);
// 或使用開放字串(僅短字串)
procedure Check(S: OpenString);
// 錯誤
procedure Sort(A: array[1..10] of Integer); // syntax error
// 正確
type
TDigits = array[1..10] of Integer;
procedure Sort(A: TDigits);
type
TDynamicArray = array of Integer;
procedure Modify(Value: TDynamicArray);
begin
Value[0] := 1; // 影響原陣列元素
end;
var
A: TDynamicArray;
begin
SetLength(A, 1); A[0] := 0;
Modify(A);
WriteLn(A[0]); // 輸出 1
end;
procedure Clear(var A: array of Real);
var I: Integer;
begin
for I := 0 to High(A) do A[I] := 0;
end;
function Sum(const A: array of Real): Real;
var I: Integer; S: Real;
begin
S := 0;
for I := 0 to High(A) do S := S + A[I];
Result := S;
end;
A[2..5])。High(A) 返回元素數-1。array of constfunction MakeStr(const Args: array of const): string;
var I: Integer;
begin
Result := '';
for I := 0 to High(Args) do
with Args[I] do
case VType of
vtInteger: Result := Result + IntToStr(VInteger);
vtBoolean: Result := Result + BoolToStr(VBoolean);
vtChar: Result := Result + VChar;
vtExtended: Result := Result + FloatToStr(VExtended^);
vtString: Result := Result + VString^;
vtPChar: Result := Result + VPChar;
vtObject: Result := Result + VObject.ClassName;
vtClass: Result := Result + VClass.ClassName;
vtAnsiString:Result := Result + string(VAnsiString);
vtCurrency: Result := Result + CurrToStr(VCurrency^);
vtVariant: Result := Result + string(VVariant^);
vtInt64: Result := Result + IntToStr(VInt64^);
end;
end;
// 調用
MakeStr(['test', 100, ' ', True, 3.14159, TForm]);
procedure FillArray(A: array of Integer; Value: Integer = 0);
// 調用
FillArray(MyArray); // Value = 0
FillArray(MyArray, 42); // Value = 42
function F(X, Y: Real = 3.5): Real; ❌ → function F(X: Real = 3.5; Y: Real = 3.5): Real; ✅| 場景 | 推薦關鍵字 | 理由 |
|---|---|---|
| 輸入簡單型別 | (值參數) | 複製開銷極小 |
| 輸入大型結構/字串/介面/動態陣列 | const | 避免複製,語義唯讀 |
| 需修改呼叫端變數 | var | 傳址可寫 |
| 純輸出、多返回值 | out | 語義清晰,自動清零托管型別 |
| 處理任意長度同類型陣列 | array of T | 統一介面,支援切片 |
| 可變參數列表 | array of const | 類型安全的可變參數 |
合理選擇參數模式,不僅能提升程式效能,更能讓 API 語義清晰、易於維護。建議新代碼預設對輸入參數使用 const,輸出參數使用 out,僅在確需修改呼叫端變數時用 var。