1. 程式人生 > >Delphi 之 第六課 過程與函式

Delphi 之 第六課 過程與函式

  這講是核心重點*****

 
  什麼是過程?什麼又是函式?過程和函式在delphi中無處不再。過程簡單的理解就是單擊一個按鈕這就是一個過程,函式和過程不一樣的地方就是函式能把這個過程的結果返回給我們,過程的關鍵字用procedure ,函式的關鍵字Function 

下面就具體講解過程與函式的定義

  過程與函式

  Pascal中的例程有兩種形式:過程和函式。理論上說,過程是你要求計算機執行的操作,函式是能返回值的計算。兩者突出的不同點在於:函式能返回計算結果,即有一個返回值,而過程沒有。兩種型別的例程都可以帶多個給定型別的引數。

  不過實際上函式和過程差別不大,因為你可以呼叫函式完成一系列操作,跳過其返回值(用可選的出錯程式碼或類似的東西代替返回值);也可以通過過程的引數傳遞計算結果(這種引數稱為引用,下一部分會講到)。

下例定義了一個過程、兩個函式,兩個函式的語法略有不同,結果是完全相同的。

procedure Hello;
begin
  ShowMessage ('Hello world!');
end;

function Double (Value: Integer) : Integer;
begin
  Double := Value * 2;
end;

// or, as an alternative
function Double2 (Value: Integer) : Integer;
begin
  Result := Value * 2;
end;

  流行的做法是用Result 給函式賦返回值,而不是用函式名,我認為這樣的程式碼更易讀。

一旦定義了這些例程,你就可以多次呼叫,其中呼叫過程可執行操作;呼叫函式能計算返回值。如下:

procedure TForm1.Button1Click (Sender: TObject);
begin
  Hello;
end;
 
procedure TForm1.Button2Click (Sender: TObject);
var
  X, Y: Integer;
begin
  X := Double (StrToInt (Edit1.Text));
  Y := Double (X);
  ShowMessage (IntToStr (Y));
end;

注意:現在不必考慮上面兩個過程的語法,實際上它們是方法。只要把兩個按鈕(button)放到一個Delphi 窗體上,在設計階段單擊它們,Delphi IDE將產生合適的支援程式碼,你只需要填上begin 和end 之間的那幾行程式碼就行。編譯上面的程式碼,需要你在窗體中加一個Edit控制元件。

  現在回到我前面提到過的程式碼封裝概念。當你呼叫Double 函式時,你不需要知道該函式的具體實現方法。如果以後發現了更好的雙倍數計算方法,你只需要改變函式的程式碼,而呼叫函式的程式碼不必改變(儘管程式碼執行速度可能會加快!)。Hello 過程也一樣,你可以通過改變這個過程的程式碼,修改程式的輸出,Button2Click 方法會自動改變顯示結果。下面是改變後的程式碼:

procedure Hello;
begin
  MessageDlg ('Hello world!', mtInformation, [mbOK],0);
end;

提示:當呼叫一個現有的Delphi 函式、過程或任何VCL方法時,你應該記住引數的個數及其資料型別。不過,只要鍵入函式或過程名及左括號,Delphi 編輯器中會出現即時提示條,列出函式或過程的引數表供參考。這一特性被稱為程式碼引數(Code Parameters) ,是程式碼識別技術的一部分。

引用引數

  Pascal 例程的傳遞引數可以是值參也可以是引用引數。值參傳遞是預設的引數傳遞方式:即將值參的拷貝壓入棧中,例程使用、操縱的是棧中的拷貝值,不是原始值。

  當通過引用傳遞引數時,沒有按正常方式把引數值的拷貝壓棧(避免拷貝值壓棧一般能加快程式執行速度),而是直接引用引數原始值,例程中的程式碼也同樣訪問原始值,這樣就能在過程或函式中改變引數的值。引用引數用關鍵字var 標示。

  引數引用技術在大多數程式語言中都有,C語言中雖沒有,但C++中引入了該技術。在C++中,用符號 &表示引用;在VB中,沒有ByVal 標示的引數都為引用。

  下面是利用引用傳遞引數的例子,引用引數用var關鍵字標示:

procedure DoubleTheValue (var Value: Integer);
begin
  Value := Value * 2;
end;

  在這種情況下,引數既把一個值傳遞給過程,又把新值返回給呼叫過程的程式碼。當你執行完以下程式碼時:

var
  X: Integer;
begin
  X := 10;
  DoubleTheValue (X);

  x變數的值變成了20,因為過程通過引用訪問了X的原始儲存單元,由此改變了X的初始值。

  通過引用傳遞引數對有序型別、傳統字串型別及大型記錄型別才有意義。實際上Delphi總是通過值來傳遞物件,因為Delphi物件本身就是引用。因此通過引用傳遞物件就沒什麼意義(除了極特殊的情況),因為這樣相當於傳遞一個引用到另一個引用。

  Delphi 長字串的情況略有不同,長字串看起來象引用,但是如果你改變了該字串的串變數,那麼這個串在更新前將被拷貝下來。作為值參被傳遞的長字串只在記憶體使用和操作速度方面才象引用,但是如果你改變了字串的值,初始值將不受影響。相反,如果通過引用傳遞長字串,那麼串的初始值就可以改變。

  Delphi 3增加了一種新的引數:out。out引數沒有初始值,只是用來返回一個值。out引數應只用於COM過程和函式,一般情況下最好使用更有效的var引數。除了沒有初始值這一點之外,out引數與var引數相同。

常量引數

  除了引用引數外,還有一種引數叫常量引數。由於不允許在例程中給常量引數賦新值,因此編譯器能優化常參的傳遞過程。編譯器會選用一種與引用引數相似的方法編譯常參(C++術語中的常量引用),但是從表面上看常參又與值參相似,因為常參初始值不受例程的影響。

  事實上,如果編譯下面有點可笑的程式碼,Delphi將出現錯誤:

function DoubleTheValue (const Value: Integer): Integer;
begin
  Value := Value * 2;      // compiler error
  Result := Value;
end;

開放陣列引數

  與C語言不同,Pascal 函式及過程的引數個數是預定的。如果引數個數預先沒有確定,則需要通過開放陣列來實現引數傳遞。

一個開放陣列引數就是一個固定型別開放陣列的元素。 也就是說,引數型別已定義,但是陣列中的元素個數是未知數。見下例:

function Sum (const A: array of Integer): Integer;
var
  I: Integer;
begin
  Result := 0;
  for I := Low(A) to High(A) do
    Result := Result + A[I];
end;

  上面通過High(A)獲取陣列的大小,注意其中函式返回值 Result的應用, Result用來儲存臨時值。你可通過一個整數表示式組成的陣列來呼叫該函式:

X := Sum ([10, Y, 27*I]);

  給定一個整型陣列,陣列大小任意,你可以直接把它傳遞給帶開放陣列引數的例程,此外你也可以通過Slice 函式,只傳遞陣列的一部分元素(傳遞元素個數由Slice 函式的第二個引數指定)。下面是傳遞整個陣列引數的例子:

var
  List: array [1..10] of Integer;
  X, I: Integer;
begin
  // initialize the array
  for I := Low (List) to High (List) do
    List [I] := I * 2;
  // call
  X := Sum (List);

  如果你只傳遞陣列的一部分,可使用Slice 函式,如下:

X := Sum (Slice (List, 5));

 

在Delphi 4中,給定型別的開放陣列與動態陣列完全相容(動態陣列將在第8章中介紹)。動態陣列的語法與開放陣列相同,區別在於你可以用諸如array of Integer指令定義變數,而不僅僅是傳遞引數。

型別變化的開放陣列引數

  除了型別固定的開放陣列外,Delphi 還允許定義型別變化的甚至無型別的開放陣列。這種特殊型別的陣列元素可隨意變化,能很方便地用作傳遞引數。

  技術上,array of const 型別的陣列就能實現把不同型別、不同個數元素組成的陣列一下子傳遞給例程。如下面Format 函式的定義(第七章中你將看到怎樣使用這個函式):

function Format (const Format: string;
  const Args: array of const): string;

  上面第二個引數是個開放陣列,該陣列元素可隨意變化。如你可以按以下方式呼叫這個函式:

N := 20;
S := 'Total:';
Label1.Caption := Format ('Total: %d', [N]);
Label2.Caption := Format ('Int: %d, Float: %f', [N, 12.4]);
Label3.Caption := Format ('%s %d', [S, N * 2]);

  從上可見,傳遞的引數可以是常量值、變數值或一個表示式。宣告這類函式很簡單,但是怎樣編寫函式程式碼呢?怎樣知道引數型別呢?對型別可變的開放陣列,其陣列元素與TVarRec 型別元素相容。

注意:不要把TVarRec 記錄型別和Variant 型別使用的TVarData 記錄型別相混淆。這兩種型別用途不同,而且互不相容。甚至可容納的資料型別也不同,因為TVarRec 支援Delphi 資料型別,而TVarData 支援OLE 資料型別。

TVarRec 記錄型別結構如下:

type
  TVarRec = record
    case Byte of
      vtInteger:    (VInteger: Integer; VType: Byte);
      vtBoolean:    (VBoolean: Boolean);
      vtChar:       (VChar: Char);
      vtExtended:   (VExtended: PExtended);
      vtString:     (VString: PShortString);
      vtPointer:    (VPointer: Pointer);
      vtPChar:      (VPChar: PChar);
      vtObject:     (VObject: TObject);
      vtClass:      (VClass: TClass);
      vtWideChar:   (VWideChar: WideChar);
      vtPWideChar:  (VPWideChar: PWideChar);
      vtAnsiString: (VAnsiString: Pointer);
      vtCurrency:   (VCurrency: PCurrency);
      vtVariant:    (VVariant: PVariant);
      vtInterface:  (VInterface: Pointer);
  end;

  每種記錄都有一個VType 域,乍一看不容易發現,因為它與實際意義的整型型別資料(通常是一個引用或一個指標)放在一起,只被聲明瞭一次。

  利用上面資訊我們就可以寫一個能操作不同型別資料的函式。下例的SumAll 函式,通過把字串轉成整數、字元轉成相應的序號、True布林值加一,計算不同型別資料的和。這段程式碼以一個case語句為基礎,雖然不得不經常通過指標取值,但相當簡單,:

function SumAll (const Args: array of const): Extended;
var
  I: Integer;
begin
  Result := 0;
  for I := Low(Args) to High (Args) do
    case Args [I].VType of
      vtInteger: Result :=
        Result + Args [I].VInteger;
      vtBoolean:
        if Args [I].VBoolean then
          Result := Result + 1;
      vtChar:
        Result := Result + Ord (Args [I].VChar);
      vtExtended:
        Result := Result + Args [I].VExtended^;
      vtString, vtAnsiString:
        Result := Result + StrToIntDef ((Args [I].VString^), 0);
      vtWideChar:
        Result := Result + Ord (Args [I].VWideChar);
      vtCurrency:
        Result := Result + Args [I].VCurrency^;
    end; // case
end;

  我已在例OpenArr中加了這段程式碼,該例在按下設定的按鈕後呼叫SumAll 函式。

procedure TForm1.Button6Click(Sender: TObject);
var
  X: Extended;
  Y: Integer;
begin
  Y := 10;
  X := SumAll ([Y * Y, 'k', True, 10.34, '99999']);
  ShowMessage (Format (
    'SumAll ([Y*Y, ''k'', True, 10.34, ''99999'']) => %n', [X]));
end;

 

Delphi 呼叫協定

  32位的Delphi 中增加了新的引數傳遞方法,稱為fastcall:只要有可能,傳遞到CPU暫存器的引數能多達三個,使函式呼叫操作更快。這種快速呼叫協定(Delphi 3確省方式)可用register 關鍵字標示。

  問題是這種快速呼叫協定與Windows不相容,Win32 API 函式必須宣告使用stdcall 呼叫協定。這種協定是Win16 API使用的原始Pascal 呼叫協定和C語言使用的cdecl 呼叫協定的混合體。

  除非你要呼叫外部Windows函式或定義Windows 回撥函式,否則你沒有理由不用新增的快速呼叫協定。 在後面你會看到使用stdcall 協定的例子,在Delphi幫助檔案的Calling conventions 主題下,你能找到有關Delphi呼叫協定的總結內容。

什麼是方法?

  如果你使用過Delphi 或讀過Delphi 手冊,大概已經聽說過“方法”這個術語。方法是一種特殊的函式或過程,它與類這一資料型別相對應。在Delphi 中,每處理一個事件,都需要定義一個方法,該方法通常是個過程。不過一般“方法”是指與類相關的函式和過程。

  你已經在本章和前幾章中看到了幾個方法。下面是Delphi 自動新增到窗體原始碼中的一個空方法:

procedure TForm1.Button1Click(Sender: TObject);
begin
  {here goes your code}
end;

Forward 宣告

  當使用一個識別符號(任何型別)時,編譯器必須已經知道該識別符號指的是什麼。為此,你通常需要在例程使用之前提供一個完整的宣告。然而在某些情況下可能做不到這一點,例如過程A呼叫過程B,而過程B又呼叫過程A,那麼你寫過程程式碼時,不得不呼叫編譯器尚未看到其宣告的例程。

  欲宣告一個過程或函式,而且只給出它的名字和引數,不列出其實現程式碼,需要在句尾加forward 關鍵字:

procedure Hello; forward;

  在後面應該補上該過程的完整程式碼,不過該過程程式碼的位置不影響對它的呼叫。下面的例子沒什麼實際意義,看過後你會對上述概念有所認識:

procedure DoubleHello; forward;

procedure Hello;
begin
  if MessageDlg ('Do you want a double message?',
      mtConfirmation, [mbYes, mbNo], 0) = mrYes then
    DoubleHello
  else
    ShowMessage ('Hello');
end;

procedure DoubleHello;
begin
  Hello;
  Hello;
end;

  上述方法可用來寫遞迴呼叫:即DoubleHello 呼叫Hello,而Hello也可能呼叫DoubleHello。當然,必須設定條件終止這個遞迴,避免棧的溢位。上面的程式碼可以在例DoubleH 中找到,只是稍有改動。

  儘管 forward 過程宣告在Delphi中不常見,但是有一個類似的情況卻經常出現。當你在一個單元(關於單元的更多內容見下一章)的interface 部分宣告一個過程或一個函式時,它被認為是一個forward宣告,即使沒有forward關鍵字也一樣。實際上你不可能把整個例程的程式碼放在interface 部分,不過你必須在同一單元中提供所宣告例程的實現。

  類內部的方法宣告也同樣是forward宣告,當你給窗體或其元件新增事件時, Delphi會自動產生相應的程式碼。在TForm 類中宣告的事件是forward 宣告,事件程式碼放在單元的實現部分。下面摘錄的原始碼中有一個Button1Click 方法宣告:

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

過程型別

  Object Pascal 的另一個獨特功能是可定義過程型別。過程型別屬於語言的高階功能,Delphi 程式設計師不會經常用到它。因為後面章節要討論相關的內容(尤其是“方法指標” Delphi用得特別多),這裡不妨先了解一下。如果你是初學者,可以先跳過這部分,當學到一定程度後再回過頭閱讀這部分。

  Pascal 中的過程型別與C語言中的函式指標相似。過程型別的宣告只需要引數列表;如果是函式,再加個返回值。例如宣告一個過程型別,該型別帶一個通過引用傳遞的整型引數:

type
  IntProc = procedure (var Num: Integer);

  這個過程型別與任何引數完全相同的例程相容(或用C語言行話來說,具有相同的函式特徵)。下面是一個相容例程:

procedure DoubleTheValue (var Value: Integer);
begin
  Value := Value * 2;
end;

注意:在16位Delphi中,如果要將例程用作過程型別的實際值,必須用far指令宣告該例程。

  過程型別能用於兩種不同的目的:宣告過程型別的變數;或者把過程型別(也就是函式指標)作為引數傳遞給另一例程。利用上面給定的型別和過程宣告,你可以寫出下面的程式碼:

var
  IP: IntProc;
  X: Integer;
begin
  IP := DoubleTheValue;
  X := 5;
  IP (X);
end;

這段程式碼與下列程式碼等效:

var
  X: Integer;
begin
  X := 5;
  DoubleTheValue (X);
end;

  上面第一段程式碼明顯要複雜一些,那麼我們為什麼要用它呢?因為在某些情況下,呼叫什麼樣的函式需要在實際中決定,此時程式型別就很有用。這裡不可能建立一個複雜的例子來說明這個問題,不過可以探究一下簡單點的例子,該例名為ProcType。該例比前面所舉的例子都複雜,更接近實際應用。

  如圖6.3所示,新建一個工程,在上面放兩個radio按鈕和一個push按鈕。例中有兩個過程,一個過程使引數的值加倍,與前面的DoubleTheValue過程相似;另一個過程使引數的值變成三倍,因此命名為TripleTheValue

procedure TripleTheValue (var Value: Integer);
begin
  Value := Value * 3;
  ShowMessage ('Value tripled: ' + IntToStr (Value));
end;

  兩個過程都有結果顯示,讓我們知道他們已被呼叫。這是一個簡單的程式除錯技巧,你可以用它來檢測某一程式碼段是否或何時被執行,而不用在程式碼中加斷點。

  當用戶按Apply 按鈕,程式會根據radio按鈕狀態選擇執行的過程。實際上,當窗體中有兩個radio按鈕時,你只能選擇一個,因此你只需要在Apply 按鈕的OnClick 事件中新增程式碼檢測radio按鈕的值,就能實現程式要求。不過為了演示過程型別的使用,我捨近求遠選擇了麻煩但有趣的方法:只要使用者選中其中一個radio按鈕,按鈕對應的過程就會存入過程變數:

procedure TForm1.DoubleRadioButtonClick(Sender: TObject);
begin
  IP := DoubleTheValue;
end;

當用戶按Apply 按鈕,程式就執行過程變數儲存的過程:

procedure TForm1.ApplyButtonClick(Sender: TObject);
begin
  IP (X);
end;

  為了使三個不同的函式能訪問IP和 X變數,需要使變數在整個窗體單元中可見,因此不能宣告為區域性變數(在一個方法中宣告)。一個解決辦法是,把這些變數放在窗體宣告中:

type
  TForm1 = class(TForm)
    ...
  private
    { Private declarations }
    IP: IntProc;
    X: Integer;
  end;

To:chris2019(牛虻---最後的匈奴)
---------------------
--------------------- 
TForm1=Class(TForm);
//這句話指是TForm1是從TForm繼乘過來的一個子類
Button1=TButton
//這種用法好象沒有
TButton1=Class(TButton)
//這句話也是指TButton1是從TButton中繼乘過來的一個子類
var
  Form1:TForm1;
//這是指定義了一個TForm1類的物件變數。 

  學完下一章,你會更清楚地瞭解這段程式碼的意思,目前只要能知道怎樣新增過程型別定義、怎樣修改相應的程式碼就行了。為了用適當的值初始化上面程式碼中的兩個變數,你可以呼叫窗體的OnCreate 事件(啟用窗體後,在Object Inspector中選擇這一事件,或者雙擊窗體)。此外最好仔細看一看上例完整的原始碼。

在第九章的 Windows 回撥函式一節,你能看到使用過程型別的例項

函式過載

  過載的思想很簡單:編譯器允許你用同一名字定義多個函式或過程,只要它們所帶的引數不同。實際上,編譯器是通過檢測引數來確定需要呼叫的例程。

下面是從VCL的數學單元(Math Unit)中摘錄的一系列函式:

function Min (A,B: Integer): Integer; overload;
function Min (A,B: Int64): Int64; overload;
function Min (A,B: Single): Single; overload;
function Min (A,B: Double): Double; overload;
function Min (A,B: Extended): Extended; overload;

當呼叫方式為Min (10, 20)時,編譯器很容易就能判定你呼叫的是上列第一個函式,因此返回值也是個整數。

宣告過載函式有兩條原則:

  • 每個例程聲明後面必須新增overload 關鍵字。
  • 例程間的引數個數或(和)引數型別必須不同,返回值不能用於區分各例程。

  下面是ShowMsg 過程的三個過載過程。我已把它們新增到例OverDef 中(一個說明過載和確省引數的應用程式):

procedure ShowMsg (str: string); overload;
begin
  MessageDlg (str, mtInformation, [mbOK], 0);
end;

procedure ShowMsg (FormatStr: string;
  Params: array of const); overload;
begin
  MessageDlg (Format (FormatStr, Params),
    mtInformation, [mbOK], 0);
end;

procedure ShowMsg (I: Integer; Str: string); overload;
begin
  ShowMsg (IntToStr (I) + ' ' + Str);
end;

三個過程分別用三種不同的方法格式化字串,然後在資訊框中顯示字串。下面是三個例程的呼叫:

ShowMsg ('Hello');
ShowMsg ('Total = %d.', [100]);
ShowMsg (10, 'MBytes');

  令我驚喜的是Delphi的程式碼引數技術與過載過程及函式結合得非常好。當你在例程名後面鍵入左圓括號時,視窗中會顯示所有可用例程的引數列表,當你輸入引數時,Delphi會根據所輸入引數的型別過濾引數列表。從圖6.4你可看到,當開始輸入一個常量字串時,Delphi只顯示第一個引數為字串的兩個ShowMsg例程引數列表,濾掉了第一個引數為整數的例程。

  過載例程必須用overload關鍵字明確標示,你不能在同一單元中過載沒有overload標示的例程,否則會出現錯誤資訊: "Previous declaration of '<name>' was not marked with the 'overload' directive."。不過你可以過載在其他單元中宣告的例程,這是為了與以前的Delphi版本相容,以前的Delphi版本允許不同的單元重用相同的例程名。無論如何,這是例程過載的特殊情況不是其特殊功能,而且不小心會出現問題。

例如在一個單元中新增以下程式碼:

procedure MessageDlg (str: string); overload;
begin
  Dialogs.MessageDlg (str, mtInformation, [mbOK], 0);
end;

這段程式碼並沒有真正過載原始的MessageDlg 例程,實際上如果鍵入:

MessageDlg ('Hello');

你將得到一個有意思的錯誤訊息,告訴你缺少引數。呼叫本地例程而不是VCL的唯一途徑是明確標示例程所在單元,這有悖於例程過載的思想:

OverDefF.MessageDlg ('Hello');

確省引數

Delphi 4 中添加了一個新功能,即允許你給函式的引數設定確省值,這樣呼叫函式時該引數可以加上,也可以省略。下例把應用程式全程物件的MessageBox 方法重新包裝了一下,用PChar 替代字串,並設定兩個確省值:

procedure MessBox (Msg: string;
  Caption: string = 'Warning';
  Flags: LongInt = mb_OK or mb_IconHand);
begin
  Application.MessageBox (PChar (Msg),
    PChar (Caption), Flags);
end;

使用這一定義,你就可以用下面任一種方式呼叫過程:

MessBox ('Something wrong here!');
MessBox ('Something wrong here!', 'Attention');
MessBox ('Hello', 'Message', mb_OK);

從圖6.5中可以看到,Delphi的 程式碼引數提示條會用不同的風格顯示確省值引數,這樣你就很容易確定哪個引數是可以省略的。

注意一點,Delphi 不產生任何支援確省引數的特殊程式碼,也不建立例程的多份拷貝,預設引數是由編譯器在編譯時新增到呼叫例程的程式碼中。

  使用確省引數有一重要限定:你不能“跳過”引數,如省略第二個引數後,不能把第三個引數傳給函式:

MessBox ('Hello', mb_OK); // error  

  確省引數使用主要規則:呼叫時你只能從最後一個引數開始進行省略,換句話說,如果你要省略一個引數,你必須省略它後面所有的引數。

  確省引數的使用規則還包括:

  • 帶確省值的引數必須放在引數表的最後面。
  • 確省值必須是常量。顯然,這限制了確省引數的資料型別,例如動態陣列和介面型別的確省引數值只能是 nil;至於記錄型別,則根本不能用作確省引數。
  • 確省引數必須通過值參或常參傳遞。引用引數 var不能有預設值。

  如果同時使用確省引數和過載可能會出現問題,因為這兩種功能可能發生衝突。例如把以前ShowMsg 過程改成:

procedure ShowMsg (Str: string; I: Integer = 0); overload;
begin
  MessageDlg (Str + ': ' + IntToStr (I),
    mtInformation, [mbOK], 0);
end;

  編譯時編譯器不會提出警告,因為這是合法的定義。

  然而編譯呼叫語句:

ShowMsg ('Hello');

  編譯器會顯示 Ambiguous overloaded call to 'ShowMsg'.( 不明確過載呼叫ShowMsg)。注意,這條錯誤資訊指向新定義的過載例程程式碼行之前。實際上,用一個字串引數無法呼叫ShowMsg 過程,因為編譯器搞不清楚你是要呼叫只帶字串引數的ShowMsg 過程,還是帶字串及整型確省引數的過程。遇到這種問題時,編譯器不得不停下來,要求你明確自己的意圖。

結束語

  過程和函式是程式設計的一大關鍵,Delphi 中的方法就是與類及物件關聯的過程和函式。

下面幾章將從字串開始詳細講解Pascal的一些程式設計元素。

下一頁: 字串操作