首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 函數參數完整指南:值/變數/常數/輸出/非強類型/開放陣列/預設參數

     編輯:Delphi

Delphi 函數參數機制豐富,支援值參數、變數參數、常數參數、輸出參數、非強類型參數、開放陣列參數、變體開放陣列與預設參數等多種模式。本文系統整理各類參數的語法、語義、效能差異與最佳實踐,附完整代碼範例。

1. 參數聲明基本語法

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);  // 非強類型

2. 值參數 vs 變數參數

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 位元組)
可修改原變數否是
可傳常數/運算式是否(必須為左值)

3. 常數參數

function CompareStr(const S1, S2: string): Integer;
  • 語義:承諾不修改參數,編譯器強制檢查。
  • 效能:對大型結構體/字串/介面/動態陣列,以引用傳遞(如 var)但禁止寫入,避免複製開銷。
  • 適用:所有輸入型參數首選 const。

4. 輸出參數

procedure GetInfo(out Info: TSomeRecord);
var
  Rec: TSomeRecord;
begin
  GetInfo(Rec);  // 調用後 Rec 包含結果
end;
  • 語義:參數僅用於輸出,調用前無需初始化(編譯器會自動清零托管類型)。
  • 適用:多返回值場景,替代 var 提升語義清晰度。

5. 非強類型參數

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;

注意:編譯器不做類型檢查,完全由開發者保證記憶體佈局相容,屬進階/底層用法。

6. 字串參數

// 錯誤:短字串長度屬類型一部分,不可直接作參數
procedure Check(S: string[20]);  // syntax error

// 正確:定義類型別名
type
  TString20 = string[20];
procedure Check(S: TString20);

// 或使用開放字串(僅短字串)
procedure Check(S: OpenString);

7. 陣列參數

靜態陣列:需定義類型別名

// 錯誤
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])。
  • 函數內部索引總是從 0 開始,High(A) 返回元素數-1。

變體開放陣列:array of const

function 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]);

8. 預設參數

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。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved