足し算だけができる簡単な電卓を作ってみましょう。
エディットに適当な数を入力して
「+」ボタンを押すと画面には現れない場所 (変数) に値が保存され、エディットは空欄になり、
その後、エディットに別な数を入力して「=」ボタンを押すと
和が求まる、というプログラムです。
まずは、フォームにコンポーネントを配置しましょう。
コンポーネント | Name |
---|---|
左のエディット | EditNumber |
右上のボタン | ButtonPlus |
右下のボタン | ButtonEqual |
このプログラムでは、整数型変数 PrevNumber を用意して、「+」ボタンが押されたらそこに値を格納するようにします (下のプログラムを参照)。
まず、「+」ボタンのイベントハンドラを書きましょう。
procedure TForm1.ButtonPlusClick(Sender: TObject); var PrevNumber: Integer; {ここで PrevNumber を用意} begin PrevNumber := StrToInt(EditNumber.Text); {値を格納する} EditNumber.Text := ''; {エディットを空欄にする} end;
次に、「=」ボタンのイベントハンドラを書きましょう。
procedure TForm1.ButtonEqualClick(Sender: TObject); begin EditNumber.Text := IntToStr(PrevNumber + StrToInt(EditNumber.Text)); end;
実行してみましょう。 すると…
「未定義の識別子 : 'PrevNumber'」というエラーが出ましたね。これは、「'PrevNumber' という変数 (か何か) を使いたいのだろうけど、そんなものは知らないよ」というエラーです。このエラーをダブルクリックすると、
エラーが発生した行が茶色で、エラーが発生した場所 (Delphi が解釈できなくなった場所) が水色で示されます。
PrevNumber は宣言したはずなのに、未定義エラーが出たのはなぜでしょうか?
実は、Delphi (PASCAL 言語) には、「モジュールの中で用意された変数は、そのモジュールの中だけで有効である」という決まりがあります。具体的に示すと次のようになります。
では、どうしたらよいのでしょう? この場合は、どのモジュールからでも利用できるように、PrevNumber を用意しましょう。コードエディタのずっと上のほうを見て、「type」で始まる次の部分を探してください。
この end; の直前で変数を宣言します。下線部を付け加えてください。(この「type」の中で宣言する場合、「var」はいりません。)
type TForm1 = class(TForm) ButtonEqual: TButton; EditNumber: TEdit; procedure ButtonPlusClick(Sender: TObject); procedure ButtonEqualClick(Sender: TObject); private { Private 宣言 } public { Public 宣言 } PrevNumber: Integer; end;
また、これで先ほどの変数はいらなくなりました。下線部を削除してください。
procedure TForm1.ButtonPlusClick(Sender: TObject); var PrevNumber: Integer; {ここで PrevNumber を用意} begin PrevNumber := StrToInt(EditNumber.Text); {値を格納する} EditNumber.Text := ''; {エディットを空欄にする} end;
実行してみましょう。 今度はちゃんと動作するはずです。
このようにどのモジュールからも利用することができる変数を、「グローバル変数 (大域変数) 」と呼びます。一方、モジュールの中で宣言された変数は「ローカル変数(局所変数)」 と呼ばれます。変数の有効範囲をスコープと言います。
「それなら、どんな変数もグローバル変数にするほうが便利なのでは?」と考える人もいるかもしれません。すべての変数をグローバル変数にするとどうなるでしょう?
※プログラミングでは、複数のモジュールで共有する必要のない限りは「ローカル変数」を使うのが鉄則とされています。