前回の授業の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); // 小数第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 lines compiled, 0.0 sec, 39248 bytes code, 2484 bytes data
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); // 小数2桁に制限
end. // 末尾の end.(ドット付き)でプログラム全体の終了を示すCode language: PHP (php)
各関数・手続きには begin と end が一組存在し、関数本体の開始と終了を表す。C/C++/JAVAの { } に相当する
WriteLn はコンソールに内容を出力し、シングルクォート ‘ ‘ は文字列リテラルを表す。WriteLn(‘A + 10 =:’, A + 10); は文字列 A + 10 =: と式の計算結果 A + 10 を順に出力する
プログラムには一番外側の beginとend. が1組だけ存在し、内部に他の関数・手続きを呼び出すメインコードを記述する
X := 15 / 5;
WriteLn(‘X is now: ‘, X); // 指数表記
WriteLn(‘X is now: ‘, X:1:2); // 小数2桁
/ は浮動小数除算で、商も浮動小数となる
最初の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}:プログラムをコンソールアプリとして指定(黒いウィンドウが起動、GUIウィンドウアプリではない)。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になるまで自身を再帰呼び出し、0になった時点で関数を抜ける。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)標準組み込み関数、変数の値を1増加させる。
var はPascalの変数宣言キーワード、変数を定義する役割。
var
Count, MyCount: Integer;Code language: JavaScript (javascript)
var:変数宣言ブロック開始
Count, MyCount:2つの変数名
Integer:整数型
上記例のvar内で宣言した変数はグローバル変数で、プログラム内の全ての手続き・関数から参照可能
関数・手続きと基本プリミティブ型