【学習内容とねらい】
本章では、「変数」について学習します。変数といっても数学の方程式に出てくる変数とはちょっと意味が違います。プログラミングの世界では、変数とは、データの記憶(格納)場所のことを指します。 ・・・ と言っても、まだピンと来ないかもしれませんね。しかし、実はすでに皆は「変数」に“遭遇”しているのです。
例えば、「エディット」コンポーネントの「Text」プロパティにはエディット欄に入っている“文字”が記憶されていますし、「Width」プロパティには“欄の横幅の値”が記憶されています。この意味でコンポーネントのプロパティは変数だったのです。
ただし、この「Textプロパティの変数」と「Widthプロパティの変数」には大きな違いがあります。というのは、Widthプロパティは「その値を2倍する」、あるいは「5を加える」などの計算(算術演算)ができるのに対し、Textプロパティには算術演算はできないからです。ですからコンピュータの中で一律に扱うことはできません。どうやら、変数はその性質に応じて“タイプ分け”しておくことが必要なようです。そこで、「変数の型」という概念が現れます。
以上を念頭において、本章の各節を一つ一つ確かめながら読み進んで行けば、「変数」および「変数の型」の概念を理解することができるはずです。また、自分独自の変数をプログラム中で定義して使用することもできるようになります(これを「変数の宣言」と言います)。
変数はプログラミングの基礎中の基礎であり、また同時に初心者がつまずきやすいところでもあります。どうか、ていねいに流れを追いながら学習して行って下さい。本章を理解すればプログラミング学習の最初の“関門”を突破したことになります。
<第3章の構成>
![]() |
3−1 「+」演算子 (1) −「エディット」による足し算−
3−2 「+」演算子 (2) −「スピンエディット」による足し算−
3−3 データの型
3−4 型変換 (1) −整数型と文字列型の相互変換−
3−5 型変換 (2) −「エディット」による足し算の完成−
3−6 改行・空白・コメント・大文字小文字
3−7 変数 (1) −変数としての Text プロパティ−
3−8 変数 (2) −宣言して使う変数−
3−9 実数型変数
3−10 定数 (1) −整数型定数−
3−11 定数 (2) −文字列型定数−
3−12 変数と定数 (1) −「スピンエディット」を作ろう−
3−13 変数と定数 (2) −「メモ」を使ってみよう
3−14 配列変数
|
という状態で「足す」ボタンを押すと足し算して |
|
と表示するプログラムを作ってみましょう。 |
まずはフォーム上にコンポーネントを配置して、次の画面を作ってください。
コンポーネント |
Name |
上のエディット |
Edit1 |
中のエディット |
Edit2 |
下のエディット |
EditResult |
ボタン |
ButtonAdd |
次に、ボタンを押したときの動作をプログラミングします。「ButtonAdd」の「OnClick」イベントに対するプログラム(イベントハンドラ)を書きましょう。下線部はどのように書くとよいでしょうか?
procedure TForm1.ButtonAddClick(Sender: TObject);
begin
:= + ;
end;
実行結果を確かめましょう。
このプログラムで、左上のエディットに「佐藤」、左中のエディットに「さん」と入れて「足す」ボタンを押すと、左下のエディットには何と表示されますか?
実は現段階では、14+31=45 のような数の足し算を実現できません。どうしたらいいでしょう? ・・・ 考えながら次節へ進んで下さい。
今度は、スピンエディットに替えて足し算をさせてみましょう。フォーム上に3つのスピンエディットを次のように配置してください。
コンポーネント |
Name |
左上のスピンエディット |
SpinEdit1 |
左中のスピンエディット |
SpinEdit2 |
左下のスピンエディット |
SpinEditResult |
右のボタン |
ButtonAdd |
ボタンを押したときの動作はどのようにプログラミングするとよいでしょうか。
procedure TForm1.ButtonAddClick(Sender: TObject);
begin
:= + ;
end;
出来上がったら、適当な数値を入れて「足す」ボタンを押し、プログラムの動作を確かめましょう。
今度はうまく足し算ができたはずです。
どうやら「エディット」コンポーネントと「スピンエディット」コンポーネントには何らかの“違い”があるようです。その種明かしは次節で行いましょう。
エディットを使った足し算とスピンエディットを使った足し算が違うのは、Edit1.Text と SpinEdit1.Value の「型」というものが違うためです。型には名前がつけられています。
プロパティ |
型の名前 |
日本語名 |
データ形式 |
足し算の結果 |
Edit1.Text |
String 型 |
文字列型 |
文字 (231文字まで) |
14 + 31 = 1431 |
SpinEdit1.Value |
Integer 型 |
整数型 |
整数(-231〜231-1まで) |
14 + 31 = 45 |
SpinEdit1.Value に次の値を入れて、SpinEdit1.Value は整数しか受け付けないことを確かめましょう。
「ヘルプ」キーを使ってプロパティの型を調べられる場合もあります。ここでは、エディットの
Text
プロパティの型を調べてみましょう。フォーム上にエディット (Edit1) を置き、オブジェクトインスペクタで Edit1 の 「Text」 をクリックし、[F1]キーを押してみましょう。
すると、Textプロパティに対するヘルプメニューが開き、その中に下の記述があるはずです。
これは、TextプロパティがTCaption型であることを意味しています。でも、TCaption型とはどのようなものか、よく分かりませんね。そこで、さらにTCaption部分をクリックすると、TCaption型の説明が現れ、そこに次の記述を確認することができます。
これは、TCaption型がstring(文字列)型であることを示しています。こうして、TextプロパティがString(文字列)型であることが分かります。
一般に[F1]キーを使うと、該当事項に関するヘルプメニューを開くことができます。この意味で、[F1]キーは「ヘルプ」キーと呼ばれています。
Edit1 の Width プロパティの型を調べてください。
ButtonAdd の Caption プロパティの型を調べてください。
「エディット」では普通の足し算はできませんでしたが、「スピンエディット」ではできました。そこで、まずは「エディット」から「スピンエディット」へのコピープログラムを作ってみましょう。次のようなフォームを作ってください。
コンポーネント |
Name |
左のエディット |
Edit1 |
真中のスピンエディット |
SpinEdit1 |
右のボタン |
ButtonAdd |
下のようにプログラムを入力してください。
procedure TForm1.ButtonAddClick(Sender: TObject);
begin
SpinEdit1.Value := Edit1.Text;
end;
実行してみましょう。
すると ・・・ 次ページへ進んで下さい。
「'Integer' と 'TCaption' には互換性がありません」というエラーが出てしまいます。これは、左辺と右辺の「型が合っていません」という意味のエラーです。
では、エディットからスピンエディットへのコピーはできないのでしょうか?
実は、Delphi には、文字列型の数字を整数型の数値に変換する StrToInt() という命令があります。Edit1.Text を StrToInt() で包むと、データは整数型となり、SpinEdit1.Value に代入できるようになります。
プログラムを次のように変更して実行してみてください。
procedure TForm1.ButtonAddClick(Sender: TObject);
begin
SpinEdit1.Value := StrToInt(Edit1.Text);
end;
上のプログラムを改変して、逆に、スピンエディットからエディットに値を移すプログラムを作りましょう。この場合、StrToInt() ではなく IntToStr() という命令を使います。
StrToInt は String 型 To Integer 型 の略です。
IntToStr は Integer 型 To String 型 の略です。
当初の目的どおり、エディットを用いて
|
という状態で「足す」ボタンを押すと足し算を行い |
|
と表示するプログラムを作りましょう。
|
と言いたいところですが・・・
3-1の【練習問題】の足し算プログラムの時のように
procedure TForm1.ButtonAddClick(Sender: TObject);
begin
EditResult.Text := Edit1.Text + Edit2.Text;
end;
というプログラムを作っても、数値としての足し算はしてくれないのでした。
そこで、ここではまず、エディットのかわりにスピンエディットに計算させるプログラムを作ります。まずは次のようにフォームを作ってください。コンポーネントの Name プロパティは自由に付けても構いません。
今まで学んできたこと(整数型 ←→ 文字列型の変換)を用いればできます。次の順に「型変換」あるいは「足し算」処理をプログラムすれば良いでしょう。
これで当初の足し算プログラムが完成しました。
上のプログラムのフォームから右下の「スピンエディット」を削除しましょう。
そのまま実行するとエラーが出ます。エラーを出さずに今までどおりに足し算ができるよう、プログラムを変更してください。
ヒント : (3) の処理と (4) の処理を一緒におこなってしまえば…。
さらに、残りの右の「スピンエディット」も削除しましょう。
そのまま実行するとエラーが出ます。エラーを出さずに今までどおりに足し算ができるよう、プログラムを変更してください。
Delphi でのルール
(1) どこで改行しても、しなくてもよい。
(2) 空白がいくつ並んでいても1つの空白とみなす。
(3) {と }で囲まれた部分、(* と *)で囲まれた部分、および「//」から行末までは無視される。
(4) 大文字と小文字の区別はない。
(1) 次の2つのプログラムは同じものです。
![]() |
procedure TForm1.Button1Click(Sender: TObject);
begin
EditResult.Text:= IntToStr(StrToInt(Edit1.Text) + StrTo…
end;
![]() |
procedure TForm1.Button1Click(Sender: TObject);
begin
EditResult.Text :=
IntToStr(StrToInt(Edit1.Text) +
StrToInt(Edit2.Text));
end;
ただし、
procedure TForm1.Button1Click(Sender: TObject);
begin
EditResult.Text := IntT
oStr(StrToInt(Edit1.Text) + StrToInt(Edit2.Text));
end;
というように字句の途中で改行してはいけません。
(2) 次のプログラムは文法的には正しいプログラムです。
procedure TForm1.Button1Click(Sender: TObject);
begin
SpinEdit1.Value:=StrToInt(Edit1.Text );
SpinEdit2.Value := StrToInt( Edit2.Text);
SpinEditResult.Value:= SpinEdit1.Value+SpinEdit2.Value;
end;
しかし、このプログラムは、「begin と end; によって囲まれた部分がプログラムである」という構造が非常にわかりにくくなっています。また、余計な空白を入れると文の意味が分かりにくくなり、誤解が生じかねません。そこで、下のように記述したらどうでしょうか?
![]() |
procedure TForm1.Button1Click(Sender: TObject);
begin
SpinEdit1.Value := StrToInt(Edit1.Text);
SpinEdit2.Value := StrToInt(Edit2.Text);
SpinEditResult.Value := SpinEdit1.Value+SpinEdit2.Value;
end;
かなりすっきりするでしょう?ここで特に注意して欲しいことは、begin と end; の間の行は先頭に空白を入れて先頭を揃えプログラムをみやすくする、という点です。これを「字下げ」といいます。字下げは、プログラムの体裁上のことなのでどうでもいいことの様に思うかもしれません。しかし、論理構造を視覚的に分かりやすく記述することは、ミスを減らす、あるいは作業効率を上げるという観点からも重要なことです。
(3) Delphi はプログラムの中に半角の「 { 」があると、そこから半角の「 } 」までを無視します。このことを利用して、プログラムに自由にコメントをつけることができます。また、「//」を利用することもできます。コメントには全角文字を使っても構いません。プログラムをわかりやすくするため、コメントを有効に使うようにしましょう。
![]() |
procedure TForm1.Button1Click(Sender: TObject);
begin
// 2数の和を求めるプログラム
SpinEdit1.Value := StrToInt(Edit1.Text); {上のEditの値}
SpinEdit2.Value := StrToInt(Edit2.Text); {中央のEditの値}
SpinEditResult.Value := SpinEdit1.Value+SpinEdit2.Value;
end;
(4) Delphi は大文字と小文字を区別しません。つまり、「Edit1.Text」も「EDIT1.TEXT」も「edit1.text」も「eDIt1.tExT」も同じものです。ですが、見易さのため、通常は「Edit1.Text」や「SpinEdit1.Value」のように、単語の先頭は大文字にします。
|
という画面で「入れ替え」ボタンを押すと |
|
上のエディットの Text プロパティ (攻撃) と下のエディットの Text プロパティ (守備) が入れ替わる、というプログラムを作りましょう。 |
まず、次のようにフォームを作ってください。
コンポーネント |
Name |
左上のエディット |
Edit1 |
左下のエディット |
Edit2 |
右のボタン |
ButtonSwap |
そして[入れ替え]ボタンをクリックした時のプログラムを下のように記述してください。
procedure TForm1.ButtonSwapClick(Sender: TObject);
begin
Edit2.Text := Edit1.Text;
Edit1.Text := Edit2.Text;
end;
上下のエディットに適当な言葉を入れて実行してみましょう。うまく動きましたか?
実はこのままではうまく入れ替えができませんね。それは何がまずいのでしょうか?また、どうしたらいいでしょうか。
うまく入れ替えを行うためには、Edit2.Textを取り敢えず保存しておく「エディット」が必要です。次のように、データの中継用のエディットを加えてください。(Tempは temporary=一時的 の略です。)
コンポーネント |
Name |
上のエディット |
Edit1 |
中のエディット |
Edit2 |
下のエディット |
EditTemp |
ボタン |
ButtonSwap |
EditTemp
以下の空欄を埋めてプログラムを完成させ、動作を確かめてください。
procedure TForm1.ButtonSwapClick(Sender: TObject);
begin
end;
このままでもプログラムは正しく動きますが、中継用エディットが画面に表示されるのは格好悪いですね。次の問に対して予想を立ててから、実行して確かめてみましょう。
予想 EditTemp の Width を 8 にしても正しく動くでしょうか?
1. エラーが出て実行できない
2. エラーは出ないが、目的通りの動作はしない
3. エラーは出ず、目的通りの動作をする
あなたの予想は 。
予想 EditTemp の Visible プロパティを False にしても正しく動くでしょうか?
1. エラーが出て実行できない
2. エラーは出ないが、目的通りの動作はしない
3. エラーは出ず、目的通りの動作をする
あなたの予想は 。
Visibleを Falseにすると、EditTempは画面から消えてしまうので、Heightや Width, Colorなどのプロパティにはどんな値を入れても意味がないですね。入れ替えに必要なのは、Textプロパティだけなのです。中継用エディットを使わない、もっとよい方法はないのでしょうか。
ここで、新しい方法を試してみます。まずは、EditTempを削除してください。EditTempを削除したので、EditTempを中継欄に使うことはできなくなりました。そこで、今消した EditTempのかわりにもっと単純な中継欄を作ります。procedureと beginの間に、次のように付け加えてください。
procedure TForm1.ButtonSwapClick(Sender: TObject);
var
Temp: String;
begin
EditTemp.Text := Edit1.Text;
Edit1.Text := Edit2.Text;
Edit2.Text := EditTemp.Text;
end;
EditTempはなくなりましたが、これで Tempという入れ物ができ、Tempが EditTemp.Textのかわりをします。EditTemp.Textは String型だったので、そのかわりとなる tempも String型でなくてはなりません。そのため「Temp: String;」と書きます。(もし Integer型が必要なら「Temp: Integer;」と書きます。) なお、「var」は「これから (Tempのような) 入れ物を宣言 (用意) するよ」という宣言です。
これで第一段階の準備はできましたが、まだ完成ではありません。次の基礎課題に進みましょう。
Temp を使って( EditTemp.Text を使わないで)プログラムを完成させるには、どのように変更するといいでしょうか。下の空欄を埋めてプログラムを完成させて下さい。
procedure TForm1.ButtonChangeClick(Sender: TObject);
var
Temp: String;
begin
:= Edit1.Text;
Edit1.Text := Edit2.Text;
Edit2.Text := ;
end;
Tempのように値を保存しておく入れ物を「変数」といいます。(入れ物への)代入によって、その値が様々に変わるからです。今の場合 Temp は画面に現れない「エディットコンポーネントのTextプロパティ」と考えて結構です。変数の名前は Tempでなくとも自由につけても構いませんが、なるべく一目見て内容がわかる名前をつけましょう。
なお、変数宣言の「var」は変数を意味する「variable」の略です。
コラム
変数の名前は原則として自由につけて構わないのですが、いくつか例外があります。
|
「Temp」という変数を用いることは、プログラムにとって必要充分な機能を提供することになります。余計なものを使わずにこうして必要充分なものを用いるようにすると、プログラムが速くなり、プログラムサイズが小さくなります。
今度はスピンエディットの入れ替えプログラムを作ってみましょう。
|
左のようなフォームを作ってください。 |
フォームができたらプログラムを書いてください。
出来上がったら、適当な数値を入れて実行してみましょう。
【基礎課題 3-5-1】で作ったプログラム
からスピンエディットおよび、ラベルも削除して下さい。
そして、変数を用いるプログラムに修正します。下線部を埋めてプログラムを完成させて下さい。
procedure TForm1.ButtonAddClick(Sender: TObject);
var
a: ;
b: ;
c: ;
begin
:= StrToInt(Edit1.Text);
:= StrToInt(Edit2.Text);
:= + ;
EditResult.Text := IntToStr( );
end;
今までどおり「足し算プログラム」として動くことを確認しましょう。
なお、変数の宣言では、
a: Integer; b: Integer; c: Integer; |
をまとめて |
a, b, c: Integer; |
a: String; b: String; c: String; |
をまとめて |
a, b, c: String; |
と、複数の変数をひとまとめにして宣言することができます。
コラム
「でも、【基礎課題3-5-3】で作ったプログラムとここで作ったプログラムと、どちらも同じく動作するけど、どちらがいいの?」という疑問を持った人がいるかもしれませんね。どちらも同じく動作するから、どちらでもいいのです。 「だけど、実行したときの速さは違うんじゃない? 【基礎課題3-5-3】で作ったプログラムの方が、命令が1行ですっきりしているから速いと思います。」なかなか鋭い質問ですね。ですが、実行する速さも同じなのです。 実は Delphi は、【基礎課題3-5-3】で作ったプログラムもここで作ったプログラムも本質的に同じものであることを理解しています。その意味で、両者は同等なプログラムなのです。 しかし、後からプログラムを見たときには、一つの式に一度にまとめて記述するよりも、こちらの様に変数を用いた方が分かりやすいということは言えます。一般に、インプットデータや、計算の答など、何らかの意味を持つ値については、いったん、変数を定義してそこに代入しておいた方が分かりやすく、また後に拡張等を行う際にもより容易になる傾向があります。 |
【基礎課題 3-8-3】を再利用して、
|
というように2つの数を入れて「平均」ボタンを押すと |
|
平均値が求まる、というプログラムを作ります。ボタンの表示は「平均」に変更しておいてください。 |
次に、イベントハンドラを変更します。2つの数の平均は、合計を2で割って求めるのですね。プログラムを次のように書き換えてください。(書き換える部分は下線部です。)
procedure TForm1.ButtonAddClick(Sender: TObject);
var
a: Integer;
b: Integer;
c: Integer;
begin
a := StrToInt(Edit1.Text);
b := StrToInt(Edit2.Text);
c := (a + b) / 2;
EditResult.Text := IntToStr(c);
end;
実行してみましょう。エラーが出て止まってしまいましたね。
これは、割り算「(a + b) / 2」の結果は一般に小数になるのに、その小数の結果を c という整数型の変数に代入しようとしたことが原因です。
このエラーを回避するため、c を整数型の変数ではなく小数を受け付ける型の変数にしてしまいましょう。小数を受け付ける型は実数型と呼ばれ、「Real」と表します。プログラムを以下のように修正してください。
procedure TForm1.ButtonAddClick(Sender: TObject);
var
a: Integer;
b: Integer;
c: Real;
begin
a := StrToInt(Edit1.Text);
b := StrToInt(Edit2.Text);
c := (a + b) / 2;
EditResult.Text := FloatToStr(c);
end;
なお、FloatToStr() とは、実数型から文字列型への変換を行う命令です。
型変換の命令は、次のものがあります。必要になったらこのページを参照してください。
整数型から文字列型へ |
IntToStr() |
文字列型から整数型へ |
StrToInt() |
実数型から文字列型へ |
FloatToStr() 又は |
文字列型から実数型へ |
StrToFloat() |
整数型から実数型へ |
(命令がなくても自動的に変換される) |
実数型から整数型へ |
Ceil(),
Floor(), Round(), Trunc() |
以上の「変換命令」使用法の詳細については、Delphiの「ヘルプ」メニュを参照して下さい。
以下にDelphiでよく用いられる算術演算子をまとめておきます。
演算 |
加算 |
減算 |
乗算 |
除算 |
商 |
剰余 |
表記 |
+ |
− |
* |
/ |
div |
mod |
※ 「a div b」はaをbで割った時の商を与えます。演算結果(例)は次の通り。
11 div 3 → 3 11 div 5 → 2
3つの数の平均を求めるプログラムを作ってください。
下のようなフォームをもつ、分数を小数にするプログラムを作ってください。
注意
今は午後3時だとします。
|
「換算」ボタンを押したら |
|
午後の時刻の12時間表記から24時間表記を求める、というプログラムを作ってみましょう。 |
下の下線部には何と書いたらいいでしょうか。
procedure TForm1.ButtonAddClick(Sender: TObject);
begin
SpinEditResult.Value := SpinEdit1.Value + ;
end;
※ コンポーネントのNameプロパティを次のようにしています。
上のスピンディット |
|
下のスピンエディット |
|
ボタン |
上のプログラムに手を加え、下2桁の西暦略記から4桁の西暦表記を求めるプログラムを作ってください。ただし、西暦2000年以降とします。
12や2000のように、いつも決まった値であるものを「定数」といいます。この定数とは対照的に、変数は、代入によってその内容(値)が変わります。
|
左上の欄に女性の名前を入れてボタンを押すと |
|
頭に「Miss」とつけるプログラムを作ります。 |
※ 実はMissやMr.などの呼称は名字(姓)につけるもので、名前にこれをつけるのは英語としては不自然なのですが、ここでは気にしないでください。
まずはフォームにコンポーネントを配置してください。
コンポーネント |
Name |
左上のエディット |
Edit1 |
左下のエディット |
Edit2 |
右のボタン |
ButtonMiss |
あとは「敬称付け」ボタンのイベントハンドラを書くだけです。下線部には何が入ると思いますか?
procedure TForm1.ButtonMissClick(Sender: TObject);
begin
Edit2.Text := + Edit1.Text;
end;
実行してみましょう。
次ページへ
下線部に単に「Miss」と入れて実行すると、「未定義の識別子 : 'Miss'」というエラーが出て止まってしまったと思います。これは、「Miss っていうのは変数 (か何か) のつもりだろうけど、どこにも用意されていないよ」という意味のエラーです。
「Miss は変数じゃない、単なる文字列 (定数) なんだ」ということを Delphi に伝えるには、「'Miss'」と書きます。つまりアポストロフィ「’」で囲みます。
プログラムを次のように修正して実行してみましょう。
procedure TForm1.ButtonMissClick(Sender: TObject);
begin
Edit2.Text := 'Miss' + Edit1.Text;
end;
次のように「さん」づけするプログラムを作りましょう。
|
→ |
|
ボタンを押すと「Hello, Delphi.」と表示するプログラムを作ってください。
|
→ |
|
次のように来年が何年か教えてくれるプログラムを作りましょう。
|
→ |
|
|
「▲」ボタンを押すと |
|
「エディット」の中身が1つ増える、という「スピンエディット」のようなプログラムを「エディット」と「ボタン」だけで作ってみましょう。 |
コンポーネント |
Name |
左のエディット |
Edit1 |
右のボタン |
ButtonInc |
まずはフォームにコンポーネントを配置しましょう。
Edit1 はそのままでは数値の計算ができないので、整数型変数 a を用意し、
(1) Edit1 から a に値を代入
(2) a の値を1増やす
(3) a から Edit1 に値を代入
の順に処理するようにしましょう。下線部を埋めてプログラムを完成させて下さい。
procedure TForm1.ButtonIncClick(Sender: TObject);
var
a: ;
begin
a := StrToInt(Edit1.Text);
a := ;
Edit1.Text := IntToStr(a);
end;
実行してみましょう。
※ このプログラムがすんなりできたら大したもの!あなたは「代入」の意味をよく理解していることになります。
上のプログラムを、値が1ずつ増えるのではなく、2ずつ増えるように変更しましょう。
メモと呼ばれるコンポーネントを使ってみましょう。メモはを使ってフォームに配置することが出来ます。
下のようなフォームのプログラムを作ってください。
オブジェクトインスペクタで Memo1 を選んで ScrollBars を ssNone から ssBoth に変えると、プログラムはどのように変わりますか?
WordWrap プロパティを False にすると、何が変わりますか? (ヒント:実行中にメモに大量の文章を入力すると違いが分かります。)
Lines プロパティの値を変えて、プログラムを実行したとき、メモに
虹と雪のバラード |
と表示されるようにしましょう。
下のように、左のメモに情報が入っている状態で、「何行目」を指定して「取り出す」ボタンを押すと
その内容が右下のエディットに取り出される、というプログラムを作ってみましょう。
まずは、フォームの上に次のようにコンポーネントを配置します。
コンポーネント |
Name |
左のメモ |
MemoMain |
右上のスピンエディット |
SpinEditGet |
右のボタン |
ButtonGet |
右下のエディット |
EditEachLine |
次に、プログラムを書きます。MemoMain の各行は、
MemoMain.Lines.Strings[行番号]
という形でアクセスすることができます。次のプログラムを作成して下さい。
procedure TForm1.ButtonGetClick(Sender: TObject);
begin
EditEachLine.Text := MemoMain.Lines.Strings[SpinEditGet.Value];
end;
注意 メモの各行は、最初が0行目、次が1行目、その次が2行目、…というように順序がつけられています(0行目から始まっています)。
コラム
他の Delphi の教科書を読んでみると、 MemoMain.Lines.Strings[2]
ではなく MemoMain.Lines[2]
という記述を用いていることがあります。本来の書き方は前者なのですが、Delphi はどちらの書き方でも同じ物と解釈するので、より簡単な後者の表記が用いられることが多いようです。ただ、Delphiの兄弟分であるC++Builderでは、後者の(省略した)記述が認められません。そこで、C++Builderを学習する際に混乱が起きないように、ここでは、本来の書き方で説明しました。 |
上の【練習問題】を改良しましょう。下の状態で「送り込む」ボタン(NameプロパティをButtonPutとします)を押すと
ここに、新たに付加したスピンエディットとボタンのNameプロパティは次に様にしてください。
[送り込む]ボタン : ButtonPut
2行目のスピンエディット : SpinEditPut
3行目に「北の国から」、4行目に「ロマンスの神様」を送り込んでみてください。プログラムはどのように動作しましたか?
・・・
4行目以降には情報が入らないですね。 → コラム参照
コラム
このプログラムで、7行目や10行目など、4行目以降に情報を送り込もうとしても、うまく行きません。これは、現在存在していない行へのアクセスをメモが許してないからなのです。 「では、100行の情報を書き込むためには、各行にアクセスできるよう、メモにあらかじめ100行の無駄なデータを書き込んでおかなくてはならないのか?」 という疑問ももっともです。 実は、Memo には Add() という、行を付け足す命令があります。プログラムを次のように変更すると、ボタンを押すたびに行が増えていきます。 procedure TForm1.ButtonPutClick(Sender: TObject); begin MemoMain.Lines.Add(EditEachLine.Text); end; |
フォームにメモを置くだけで MemoMain.Lines.Strings[0], MemoMain.Lines.Strings[1], MemoMain.Lines.Strings[2], …が利用できるようになったように、普通の変数も1行の宣言だけでいくつもの入れ物を用意することができます。
【基礎課題 3-13-2】からメモを削除し、その代わりとなる変数を使って同じプログラムを作りましょう。MemoMain.Lines.Strings[0]、MemoMain.Lines.Strings[1],・・・の代わりに、Data[0]、Data[1]、・・・という新しい変数を導入することにします。変数名Dataは適当に付けた変数名です。
まずは、【基礎課題 3-13-2】のプログラムから MemoMain
を削除し、代わりにプログラムコードの上の方に次の下線部を挿入してください。
![]() |
type
TForm1 =
class
(TForm)
SpinEditGet: TSpinEdit;
Label1: TLabel;
ButtonGet: TButton;
EditEachLine: TEdit;
SpinEditPut: TSpinEdit;
Label2: TLabel;
ButtonPut: TButton;
procedure ButtonGetClick(Sender: TObject);
procedure ButtonPutClick(Sender: TObject);
private
{ Private
宣言
}
public
{ Public
宣言
}
Data: Array of String;
end
;
これで、Data[0]
, Data[1]
, Data[2]
, …というように、いくつもの文字列型変数を使う準備 (の第1段階) が出来ました。このときの 0
, 1
, 2
, … を添え字といいます。そして、このように添え字がつく変数を配列変数と呼びます。
でも、…, Data[100]
, Data[101]
, Data[102]
, … と続いていって、添え字はどこまで使えるようになっているのでしょうか (メモリをどれだけ準備しているでしょうか)?
実は、「配列 (の要素) が実際に何個必要か」は、プログラムの中で指示してやる必要があります。フォームに次のようにボタン (Nameプロパティを
ButtonSetSize
とします
) を配置し、そのイベントハンドラに次のように書いて下さい。
procedure
TForm1.ButtonSetSizeClick(Sender: TObject);
begin
SetLength(Data, 100);
end
;
これで、100個の変数 Data[0]
, Data[1]
, Data[2]
, …, Data[99]
が用意されました。もし変数の数が100個で足りなくなった場合も、同じ命令で変数の数を増減させることが出来ます。
では、プログラム本体部分を変更して、メモがないこのプログラムが正しく動くようにしましょう。空欄部分は自分で埋めて下さい。
![]() |
procedure
TForm1.ButtonGetClick
(Sender: TObject);
begin
EditEachLine.Text := Data[SpinEditGet.Value];
end
;
![]() |
procedure
TForm1.Button
Put
Click
(Sender: TObject);
begin
:= EditEachLine.Text;
end
;
では、実行して動作を確認してみましょう。
最初に「100個用意」ボタンを押して下さい。これで100個の変数が使えるようになります。(押し忘れると、1個の変数も使えるようにならないため、エラーが発生します。)
1. 「睦月」という文字列を「0」行目へ「送り込む」。
2. 「如月」という文字列を「1」行目へ「送り込む」。
3. 「0」行目から文字列を「取り出す」と「睦月」と表示される。
4. 「むつき」という文字列を「0」行目へ「送り込む」。
5. 「1」行目から文字列を「取り出す」と「如月」と表示される。
6. 「0」行目から文字列を「取り出す」と「むつき」と表示される。
正しく動きましたか?