その4-<プログラムの基本構造

岡本安晴 2000.11.02;2001.2.20
Object Pascal 入門
その4
プログラムの基本構造
4-1
Pascal プログラムの基本形
4-2
ユニット
4-3
フォームとユニット
4-1
岡本安晴 2000.11.02;2001.2.20
4
プログラムの基本構造
Pascal プログラムの基本形は本来単純明快なものである。しかし、Windows でのプログ
ラミングでは、フォームという Windows を基礎とするグラフィカル・ユーザー・インター
フェースによる入出力を用いるため、プログラミングにおける主たる構成要素として、主
プログラム、フォーム、およびフォームに関係するイベントの処理を記述するユニットの
3つが少なくとも必要である(付録2「Delphi のファイル」参照)
。本章においては、こ
れらについて説明する。
4-1
Pascal プログラムの基本形
Delphi においては、Windows での標準のプログラムは GUI アプリケーションという形
式のものである。これはフォーム上のビジュアル・コンポーネントによるユーザー・イン
ターフェースに基づくものである。この GUI アプリケーションの場合、フォームに関連す
るイベントと、イベントの生起によって実行される手続き(イベントハンドラという)と
の組み合わせによってプログラミングを行う。フォームとイベントハンドラは、拡張子
が.dfm のフォームファイルと.pas のユニットファイルによって記述される。これらのファ
イルをまとめ、プログラムの構造上の中心となるものが拡張子.dpr のプロジェクトファイ
ルであり、これは Delphi によって自動的に管理される。
Delphi では、フォームを用いないコンソールアプリケーションという形式のプログラム
もある。このコンソールアプリケーションは、Pascal プログラムの基本的な構成を最も簡
単な形で示すのに適したものである。。
コンソールアプリケーションの簡単なものはリスト 4.1 のようになる。
リスト 4.1
コンソールアプリケー
ションの簡単な例
{$AppType Console}
program PDemo;
begin
writeln('Hello !');
readln;
end.
先頭の「{$AppType Console}」は、このプログラムがコンソールアプリケーションであ
4-2
岡本安晴 2000.11.02;2001.2.20
ることを示すもので、コンパイラ指令と呼ばれているものの1つである。Delphi では{$、
あるいは(*$に続くコメントの形でコンパイラ指令をおく。このコンパイラ指令は Pascal
の構文とは別のものと考える。
2行目の program∼の行から Pascal のプログラムが始まる。この行に続く begin∼end
の部分がこのプログラムで実行されるものである。最初の writeln は右の(
)で囲まれ
た部分を書き出すものである。上の場合、下図
のように DOS 窓と呼ばれる Window が表示されてその画面内に書き出される。ただし、
上図は表示された Window のドラッグによってサイズを変えたものである。DOS 窓とかコ
ンソールという言い方は、昔の MS-DOS パソコンのディスプレイあるいは UNIX のコン
ソールディスプレイに似せたものであることによる。また、コンソールアプリケーション
を Delphi 上で実行したときは、プログラムにエラーがあるとき、あるいは実行時エラーが
生起したときに統合環境が十分に機能しないので注意が必要である。
writeln の次の readln は、キーボードからの Enter キーの押下を待つものである。Enter
キーを押すと、readln は終了して上のプログラムの実行の終了となる。
Object Pascal のプログラムはピリオド.で終わる.
Object Pascal の基本構造は、次のようになっている。
プログラム
プログラムヘッダー
プログラムブロック
リスト 4.1 の例では、program∼の行がプログラムヘッダーであり、それに続く部分がプ
ログラムブロックである。program∼の前の行{$∼はコメントの形であるので、プログラム
の構造としては無視する.
プログラムヘッダーは次の形のものである。
4-3
岡本安晴 2000.11.02;2001.2.20
プログラムヘッダー
program
識別子 ? ( 識別子リスト ) ? ;
program に続けてプログラムの名前(識別子)をおく。次の?で挟まれた部分は、書いて
あっても Delphi では無視される。プログラムヘッダーの最後はセミコロン;を付けて終わ
る。プログラムのファイルは、プログラムの識別子に拡張子.dpr を付けた名前をファイル
名とする。この約束に従わないファイル名を与えると、Delphi で開いたときにエラーとな
る。リスト 4.1 のコンソールアプリケーションの例の場合、プログラムのファイル名は
PDemo.dpr とする。
プログラムブロックは次の形のものである。
プログラムブロック
? uses 節 ?
ブロック
uses 節は使用するユニット名を書くものであるが、ユニットについては 4-2 節「ユニッ
ト」において説明する。
ブロックは宣言部と複合文よりなる(1-1 節「手続き」参照)
。宣言部は必要がないなら
ば省くことができる.
リスト 4.1 のプログラム例は Delphi 5用であるが、Delphi 3で開くとエラーが出る。こ
れは、Delphi 3の場合、プログラムは uses 節を持たなければならないからである。使わ
なくても適当なユニットを次の例のように宣言しておく。
{$AppType Console}
program PDemo1;
uses Windows;
// Delphi 3のときに必要な行
begin
writeln('Hello !');
readln;
end.
4-4
岡本安晴 2000.11.02;2001.2.20
コンソールアプリケーションは Delphi において作成することもできるが、メモ帳など他
のテキストエディタで作成しておいて Delphi から開く方が簡単である。例えば、Delphi 5
で作成するときは、一度「ファイル|すべて閉じる」メニュでファイルをすべて閉じてか
ら「ファイル|新規作成」でテキストファイルを新規に開く。
メモ帳、あるいは Delphi のテキストエディタで下図
のようにプログラムを書き込んでから、ファイル名をプログラム名 PDemo に合わせて
PDemo.dpr として保存する。
名前を対応させる
「
すべてのファイル」
とする
メモ帳で保存するときは、ファイルの種類は「すべてのファイル」を選ぶ。これは右端
4-5
岡本安晴 2000.11.02;2001.2.20
の下向き三角のクリックで選ぶことができる。標準の「テキスト文書(*.txt)
」のままに
しておくと、ファイル名の最後に拡張子.txt が自動的に付いてしまう。
コンソールアプリケーションとして用意したプログラムは、拡張子が.dpr のファイルの
みであっても、
Delphi から開いて実行することができる。
実行すると、DOS 窓が開いて write
あるいは writeln 文による書き出しが DOS 窓内の画面で行われ、キーボードからの入力が
read あるいは readln 文によって行われる。プログラムの最後まで実行が終わると DOS 窓も
閉じられる。プログラムの最後の実行文を「readln;」としておくと、Enter キーの押下を
待って DOS 窓が閉じられる。
write,writeln,read,readln については、5-2.4 節「ファイル型」
、付録4「テキスト(文
字列)の簡単な入出力」において説明する。
4-6
岡本安晴 2000.11.02;2001.2.20
4-2.ユニット
宣言部の一部をユニットとして別のファイルに置くことができる。このことを次のプロ
グラムについて説明する。
リスト 4.2
コンソールアプリケーション
{$AppType Console}
program PDemoU;
//uses Windows; // Delphi3 のときはこの uses 節を有効にする
var n, sum, i : Longint;
begin
write('n = ');
readln(n);
sum:=0;
for i:=1 to n do sum:=sum+i;
writeln('sum = ',sum);
readln;
end.
上のプログラムを Delphi 3で開くときは、3行目の「//uses∼」における先頭のコメント
記号「//」をとって、
「uses Windows;」とする。
リスト 4.2 のプログラムを実行したときの画面は、次のようになる。
write(‘
n = ‘)の実行で「n = 」までが表示される。
「10」とキーボードから入力した後、Enter
キーを押すと、readln(n)によってnに 10 が読み込まれる。このnの値に基づいて sum に
和が求められ、writeln(‘
sum = ‘
,sum)の実行によって「sum = 55」が表示される。write あ
るいは writeln 文の実行によって右側の(
)内のものが DOS 窓に書き出されて表示され
4-7
岡本安晴 2000.11.02;2001.2.20
るが、複数のものを1つの write あるいは writeln 文によって書き出すときは(
)内に
書き出すものをコンマ,で区切って並べる。
「sum = 55」を表示した後、readln 文が実行され Enter キーが押されるのを待つ。Enter
キーが押されると readln 文が終了し、プログラムの実行も終了して DOS 窓が閉じられる。
リスト 4.2 のプログラムにおいて、和を求める部分を手続き CalcSum としてまとめると
次のようになる。
リスト 4.3
手続き CalcSum
{$AppType Console}
program PDemoU1;
//uses Windows; // Delphi3 のときはこの uses 節を有効にする
var n, sum : Longint;
procedure CalcSum( n : Longint; var Sum : Longint );
var i : Longint;
begin
sum:=0;
for i:=1 to n do sum:=sum+i;
end;
begin
write('n = ');
readln(n);
CalcSum(n, sum);
writeln('sum = ',sum);
readln;
end.
リスト 4.3 のプログラムにおいて、手続き CalcSum の部分を別のファイルに置くことを
考える。別のファイルとする簡単な方法としてインクルードファイルとするものがあるが、
ここではユニットとしてまとめる方法について説明する。
手続き CalcSum をユニットにまとめると次のようになる.
4-8
岡本安晴 2000.11.02;2001.2.20
リスト 4.4
ユニット UCalc
unit UCalc;
interface
procedure CalcSum( n : Longint; var Sum : Longint );
implementation
procedure CalcSum( n : Longint; var Sum : Longint );
var i : Longint;
begin
sum:=0;
for i:=1 to n do sum:=sum+i;
end;
end.
上のユニットの構造は次のようになっている。
すなわち、
「unit UCalc;」のユニットヘッダー、interface で始まるインターフェース部、
implementation で始まる実現部の3つから構成されている。ユニットの最後には end とピ
4-9
岡本安晴 2000.11.02;2001.2.20
リオド.をおく。ユニットのインターフェース部に宣言されているものがユニットの外か
ら利用することができる。手続きおよび関数の宣言は実現部で行う。ユニットの外から利
用する手続きや関数は、それらのヘッダー部のみをインターフェース部でも宣言しておく。
リスト 4.4 の例では手続きヘッダー
procedure CalcSum( n : Longint; var Sum : Longint );
がインターフェース部で宣言されている。
実現部で宣言されている手続きや関数は、それらのヘッダーがインターフェース部にお
いても宣言されていないときはユニットの外からは呼び出すことができない。また、イン
ターフェース部には手続きや関数のヘッダーのみを宣言し、それらのブロックの宣言はイ
ンターフェース部では行わず、実現部において完全な形の手続き宣言や関数宣言を行う。
インターフェース部で宣言された変数などの識別子はそのユニットおよびユニットの外
から利用可能であるが、実現部で宣言された識別子はその実現部においてのみ利用可能で
ある。また、Pascal においては、宣言された識別子はその位置以降で有効であるという原
則がある。したがって、ユニットにおいても、宣言された識別子はユニット内のその位置
以降において有効である。
ユニットの形は、一般的には次のようになる。
ユニット
ユニットヘッダー
インターフェース部
実現部
? 初期化部 ?
? 終了部 ?
end.
ユニットヘッダーは次の形のものである。
4 - 10
岡本安晴 2000.11.02;2001.2.20
ユニットヘッダー
unit
識別子 ;
ユニットヘッダーで与えた識別子がユニットの名前となる。ユニットを格納するファイル
の名前は、この識別子に拡張子.pas を付けたものとする。リスト 4.4 の場合、ファイル名
は UCalc.pas となる。
インターフェース部は、次の形のものである。
インターフェース部
interface
? uses 節 ?
? インターフェース宣言 % .
.
.インターフェース宣言 % ?
uses 節には、他のユニットを利用するときにそのユニット名を書く。他のユニットを利用
しないときは、uses 節を置く必要はない。uses 節には、利用するユニット名を次のように
並べる。
Uses 節
Uses 識別子 % , .
.
., 識別子 % ;
インターフェース宣言には、次のものがある。
インターフェース宣言
|変数宣言部|型宣言部|定数宣言部|エクスポートヘッダー|
4 - 11
岡本安晴 2000.11.02;2001.2.20
インターフェース部における手続きや関数のヘッダーは、エクスポートヘッダーと呼ば
れている。
エクスポートヘッダー
|手続きヘッダー; ? 指令 ? |関数ヘッダー; ? 指令 ? |
実現部は、次の形のものである。
実現部
implementation
? uses 節 ?
? 宣言部 % .
.
.宣言部 % ?
他のユニットを利用する場合、uses 節にそのユニット名を書くが、すでにインターフェー
ス部における uses 節においてそのユニット名が書かれているときは実現部に書く必要はな
い。他のユニットで宣言されている識別子を実現部のみで使用するときは、そのユニット
名を実現部の uses 節に書いておけばよい。他のユニットで宣言されている識別子がインタ
ーフェース部において使用されているときは、インターフェース部における uses 節にその
ユニット名を書いておく。
初期化部および終了部は、必要ならば置くことができる。初期化部はプログラムの実行
開始時に実行されるものであり、終了部はプログラムの実行が終了するときに実行される。
上のユニット UCalc を用いるプログラムは、次のようになる。
{$AppType Console}
program PDemoU2;
uses UCalc;
var
n, sum : Longint;
begin
4 - 12
岡本安晴 2000.11.02;2001.2.20
write('n = ');
readln(n);
CalcSum(n, sum);
writeln('sum = ',sum);
readln;
end.
上のプログラムでは、手続き CalcSum はユニット UCalc(リスト 4.4)に宣言されている
ものである。
4 - 13
岡本安晴 2000.11.02;2001.2.20
4-3
フォームとユニット
Delphi の標準のプログラム、GUI アプリケーション、では、主プログラムは次のようにな
っている。
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
uses 節にある「Unit1 in ‘Unit1.pas’ {Form1};」で指定されているユニット Unit1 にイ
ベントに対する処理を記述する。このユニットはフォーム Form1 に関するものであること
がコメント{Form1}の形で示されている。フォーム Form1 は、複合文内の2行目の文
Application.CreateForm(TForm1, Form1);
の実行によって生成される。
ユニットのプログラミングにおける最初の状態は、次のようになっている。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
4 - 14
岡本安晴 2000.11.02;2001.2.20
TForm1 = class(TForm)
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
end.
実現部におけるコメントの形で置かれている{$R *.DFM}によって、ユニット名(この場合
は Unit1)に拡張子.dfm を付けたファイル名をもつフォームファイルと関係付けられる。
フォームファイルは、Delphi のエディタで開くとテキストファイルとして内容が表示され
る。フォームは、インターフェース部で宣言されているクラス型 TForm1 の変数 Form1 とし
て宣言されているもので表されている。
なお、プログラムで用いるボタンなどの入出力用インターフェースのフォーム上での配
置などはビジュアルに行える。フォーム上でのビジュアルな設計については、付録1「イベ
ントとイベントハンドラ」
、付録7「コンポーネント」を参照せよ。
4 - 15
岡本安晴 2000.11.02;2001.2.20
参考文献
(1) Delphi 5オンラインヘルプ、Inprise Corporation, 1999.
(2) Delphi 5 Object Pascal 言語ガイド、インプライズ株式会社、1999.
(3) 岡本安晴「Delphi プログラミング入門」
、CQ 出版社、1997.
4 - 16