修改上一堂課的dpr檔案,替換為以下內容
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
program MyProgram;
procedure MyProcedure(const A: Integer);
begin
WriteLn('A + 10 is: ', A + 10);
end;
function MyFunction(const S: string): string;
begin
Result := S + 'strings are automatically managed';
end;
var
X: Single;
begin
WriteLn(MyFunction('Note: '));
MyProcedure(5);
// 斜線「/」除法永遠產生浮點數結果,若要整數除法請使用「div」
X := 15 / 5;
WriteLn('X is now: ', X); // 科學記號輸出
WriteLn('X is now: ', X:1:2); // 限制小數兩位
end.Code language: PHP (php)
D:\fpcdemo>fpc mydemo.dpr
Free Pascal Compiler version 3.2.2 [2021/05/15] for i386
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling mydemo.dpr
Linking mydemo.exe
20 行編譯完成,0.0 秒,39248 位元組程式碼,2484 位元組資料
D:\fpcdemo>mydemo
Note: strings are automatically managed
A + 10 is: 15
X is now: 3.000000000E+00
X is now: 3.00
D:\fpcdemo>Code language: CSS (css)

下方為逐行註解說明。非英文字元可能出現亂碼,請設定主控台編碼以正常顯示繁體中文。
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
program MyProgram;
// 自訂程式名稱。Pascal 主控台程式必須以 program 名稱; 開頭,後續宣告變數、程序與主執行程式碼
// 無回傳值:procedure 程序。程序與函式僅在被呼叫時才會執行
procedure MyProcedure(const A: Integer);
begin
WriteLn('A + 10 =:', A + 10);
end;
// 有回傳值:function 函式
function MyFunction(const S: string): string;
begin
Result := S + '字串記憶體由系統自動管理';
end;
// Object Pascal 沒有 main 函式,最外層 begin...end. 區塊為程式進入點,以下是主區塊
var
X: Single; // 單精準度浮點基礎型別
begin
// 所有要執行的邏輯皆寫在此處
WriteLn(MyFunction('提示:'));
MyProcedure(5);
// 運算子「/」永遠回傳浮點數,整數除法使用 div
X := 15 / 5;
WriteLn('X is now:', X); // 自動以科學記號輸出
WriteLn('X is now:', X:1:2); // 限定輸出兩位小數
end. // end. 加上句號代表整支程式結束Code language: PHP (php)
每個函式與程序都有一組 begin、end 標示函式本體的開頭與結尾,等同 C、C++、JAVA 的大括號 { }。
WriteLn 會將內容輸出至主控台,單引號 ‘ ‘ 包覆字串常值。WriteLn('A + 10 =:', A + 10); 會依序輸出字串 A + 10 =: 以及運算結果 A + 10。
一支程式只能有一組最外層的 begin 與 end. 區塊,內部放置主程式碼,並呼叫其他函式、程序。
X := 15 / 5;
WriteLn(‘X is now: ‘, X); // 科學記號
WriteLn(‘X is now: ‘, X:1:2); // 兩位小數
/ 為浮點除法,商永遠是小數型數值。
最前兩行是前置編譯指令
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}Code language: PHP (php)
這是 FPC 專屬條件式編譯指令
{$ifdef FPC}:只有編譯器為 Free Pascal 時,才執行中間的設定{$mode objfpc}:切換至 ObjFpc 語法模式{$H+}:啟用 長字串(具自動記憶體管理的現代 string 型別,必要設定){$J-}:停用可變常數(常數執行期不可修改,提升安全性){$endif}:條件區塊結尾
作用:僅在使用 FPC 編譯時開啟現代語法;Delphi 編譯器會忽略整個區塊。
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}Code language: PHP (php)
跨平台條件編譯
MSWINDOWS:僅在 Windows 作業系統生效{$apptype CONSOLE}:將程式定義為 主控台應用程式(開啟黑色終端視窗,而非圖形介面視窗)。在 Linux/macOS 編譯時此行會被忽略。
核心知識重點
string原生基礎型別;FPC/Delphi 自動管理記憶體,不需手動釋放- procedure 程序:無回傳值;function 函式:具回傳值,儲存於內建變數
Result - 除法區分:
/浮點除法;div截斷小數的整數除法 - 格式化輸出
變數:總寬度:小數位數控制浮點數顯示格式 - 無參數遞迴函式必須加上空括號
(),避免語義歧義 Exit(數值)可直接指定回傳值並提前離開函式- 函式可忽略回傳值直接呼叫,適用於修改全域變數等帶有副作用的邏輯
函式回傳值規則
- 內建特殊變數
Result存放函式回傳數值,讀寫方式與區域變數完全相同
function MyFunction(const S: string): string;
begin
Result := S + 'One';
Result := Result + 'Two';
end;
Code language: PHP (php)
- 舊式語法允許直接對函式名稱賦值(
MyFunction := xxx),可讀性差不建議使用,統一使用Result。
C/C++/Java/C# 使用
=賦值、==相等比較。Pascal 剛好相反::=用於變數賦值,單一個=做相等判斷,與數學記號規則一致。Pascal 不存在
==運算子
將範例原本的 MyFunction 替換為上方版本。此函式會在呼叫傳入的字串後面先串接 One,再接 Two。
最終回傳字串:原始字串 + One + Two
遞迴呼叫
無參數函式做遞迴呼叫時,必須加上空括號 (),區分「執行呼叫函式」與「讀取當前回傳值」:
function SumIntegersUntilZero: Integer;
var I: Integer;
begin
ReadLn(I);
Result := I;
if I <> 0 then
Result := Result + SumIntegersUntilZero(); // 遞迴呼叫需帶 ()
end;
Code language: JavaScript (javascript)
無參數函式 SumIntegersUntilZero 兩種寫法差異說明:
SumIntegersUntilZero()→ 遞迴執行函式並取得回傳值SumIntegersUntilZero→ 存取內部變數Result(函式自身的回傳值)
移除括號後的程式碼:
Result := Result + SumIntegersUntilZero;
編譯器會解讀成:
Result := Result + Result;
等同 Result := Result * 2,整份遞迴邏輯完全失效,產生無限迴圈且數值持續加倍。
本範例邏輯:函式會持續呼叫自身,直到輸入數值為 0 才結束;只要輸入不為零,遞迴就會持續執行。
Exit:提前結束函式
- 無參數 Exit:立即離開函式,回傳已賦值完成的 Result
Exit(數值):直接指定回傳值並終止函式,等同 C 語言的 return x
function AddName(const ExistingNames, NewName: string): string;
begin
if ExistingNames = '' then
Exit(NewName); // 直接回傳 NewName 並中斷執行
Result := ExistingNames + ', ' + NewName;
end;
Code language: PHP (php)
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
program MyProgram;
procedure MyProcedure(const A: Integer);
begin
WriteLn('A + 10 is: ', A + 10);
end;
function AddName(const ExistingNames, NewName: string): string;
begin
if ExistingNames = '' then
Exit(NewName);
Result := ExistingNames + ', ' + NewName;
end;
var
X: Single;
begin
WriteLn(AddName('Tom','Jack'));
WriteLn(AddName('Tom',''));
WriteLn(AddName('','Jack'));
end.Code language: PHP (php)
將函式當程序呼叫(忽略回傳值)
即便函式具有回傳值,也可只執行邏輯而忽略結果;適用於修改全域變數等具備副作用的程式邏輯:
var
Count, MyCount: Integer;
function CountMe: Integer;
begin
Inc(Count); // 副作用:全域變數加一
Result := Count;
end;
begin
Count := 10;
CountMe; // 捨棄回傳值,僅執行邏輯,Count 變成 11
MyCount := CountMe; // 儲存回傳數值,Count 變成 12
end.
Code language: PHP (php)
完整可執行範例
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
program MyProgram;
var
Count, MyCount: Integer;
function CountMe: Integer;
begin
Inc(Count);
Result := Count;
end;
begin
Count := 10;
WriteLn(CountMe);
MyCount := CountMe;
WriteLn(MyCount);
end.Code language: PHP (php)
Inc 是 Pascal(FPC/Delphi)內建標準函式,功能為將變數數值加一。
var 是 Pascal 的變數宣告關鍵字,用途為定義變數。
var
Count, MyCount: Integer;Code language: JavaScript (javascript)
var:開啟變數宣告區塊
Count, MyCount:兩個變數名稱
Integer:整數型別
本範例 var 區塊宣告的變數屬於全域變數,整支程式所有程序、函式皆可存取使用。
函式、程序與基礎原生型別