第4章         制御命令

 

【学習内容とねらい】

 これまで学習したプログラムは、上から順番に1行ずつ処理を行うというものでした。これは処理の流れの基本形ですが、身の回りを見渡してみてもこれだけでは記述できない処理が多々あります。

例えば、銀行のATMを考えてみましょう。この場合、ATMはインプットした暗証番号が正しいかどうかを判定して、正しければお金の引き出し等に応じ、間違っていれば処理を中断するようになっています。つまりある条件の判定結果に応じて処理内容を分けている分岐させている)訳です。このような処理を「分岐処理」と言います。さらに、インプットした暗証番号が正しくなかった場合、ATMは番号が間違っている旨のメッセージを表示した上で、操作をやり直すために最初の画面に戻します。これは、操作を何度か繰り返す、つまり「繰り返し処理」に当たります。

プログラミング言語にも、当然この「分岐処理」と「繰り返し処理」の命令が用意されています。これらの命令は、処理を分岐したり、元に戻したりというように処理の流れを制御するので「制御命令」と呼ばれています。本章では、この「制御命令」の使い方を学習します。

ところで、ある処理の論理的手順(・・を行ったあと、・・を実行する等のような手順)を「アルゴリズム」と言います(本来の数学的定義からすると少しあいまいですが、ここでは問題ではありません)。ある処理のプログラムを書くという作業は、そのアルゴリズムを考案・作成するということです。そしてどのような複雑なアルゴリズムでも、この「分岐処理」と「繰り返し処理」の組み合わせによって記述することができます。ですから、本章の学習を終えれば皆は、プログラミングの基本的な“表現能力”を身に付けることになります。その意味で本章はプログラミング学習の“メインイベント”と言えるでしょう。

なお、一般に、初学者は「分岐処理」は比較的理解できるが、「繰り返し処理」の理解につまずくことが多い、と言われています。本章の後半がそれに当たりますが、どうかじっくりと学習してこの“定説”をくつがえして下さい。

<本章の構成>

 


4−1  分岐処理(1)−2分岐(if thenelse文)−

4−2  分岐処理(2)−多分岐(if文の中のif文)−

4−3  分岐処理(3)−2分岐の特殊な形(if then〜文)−

4−4  分岐処理(4)−多分岐(case文)−

4−5  繰り返し処理(1)−累乗−

4−6  繰り返し処理(2)for文の導入−

4−7  繰り返し処理(3)for文の流れの観察(デバッガ利用)

4−8  繰り返し処理(4)−カウント用変数を使ったプログラム−

4−9  繰り返し処理(5)−回数が定まっていない繰り返し−

4−10 繰り返し処理(6)while文の導入−


4-1 分岐処理 (1) ―2分岐(if then〜else〜文)―

 

以前、【基礎課題1-7-3】で、下のようなフォームのプログラムを作りました。


このプログラムでは、

1.       チェックされた項目の数を数える。

2.       その数に応じて、診断結果を出す。

という2つの部分が必要です。


今回、このプログラムに、2. の機能をつけ加えてみましょう。


1. については、今回は考えません。項目の数は自分で数えることにします。

 

 

【基礎課題 4-1-1】

 

このプログラムを新しい名前で保存してから、下のようなフォームのプログラムに作り替えて下さい。


主なコンポーネントのNameプロパティは、次のようにして下さい。

コンポーネント

Name

ボタン「診断」

ButtonDiag

スピンエディット「チェック項目数」

SpinEditSum

チェックボックス「6-10」

CheckBoxHigh

チェックボックス「0-5」

CheckBoxLow

エディット

EditMessage

 


「チェック項目数」を入力してから「診断」ボタンを押したとき、

 

 

ようなプログラムを作りましょう。

ある条件が成り立っているか成り立っていないかによって行う内容が変わる場合には、「if文」を用いて表します。

 

「診断」ボタンをクリックしたときのイベントハンドラを、次のように書いて下さい。


注意 面倒でも、半角スペース2字分ずつの「字下げ」を必ず行って下さい。構造が見やすくなります。


この命令は、下のような構造になっています。

 


 if文は、条件が成り立っているか成り立っていないかによって、プログラムの流れを分岐させます。

 

 

 

 

条件は、

のどちらかしかありません。したがって、プログラムは、

どちらかひとつを必ず実行し、かつ、いずれかひとつしか実行しません。

 

数学表記 

     意味

Delphiでの表記

A>B 

AはBより大きい

   A>B

A≧B 

AはB以上 

   A>=B

A=B 

AはBに等しい 

   A=B

A≦B

AはB以下

   A<=B

A<B 

AはBより小さい 

   A<B

A≠B

AはBに等しくない

<>B

 

 Delphiでの不等号記号の書き方は右表の通りです。

 

 

 

 

 

注意 Delphiでは、代入の「:=」と比較の「=」を使い分けます。混同しやすいので注意してください。

 

【練習問題】

 上で学習したif分の使い方をもう少し練習してみましょう。

 

 

上のようなフォームを作り、「診察を希望する」チェックボックスがチェックされているかどうかによって

 

状態

メッセージ

チェックされている

来週水曜正午から、公民館で健康診断が行われます。
無料です。

チェックされていない

ストレスを溜めない生活を心掛けましょう。
体を大切に。

 

というメッセージが表示されるプログラムを作りましょう。「OK」ボタンのイベントハンドラを次のように書いて下さい。

 


procedure TForm1.ButtonOKClick(Sender: TObject);

begin

  if (CheckBoxDoctor.Checked = True)

    then

      begin

        Edit1.Text := '来週水曜正午から、公民館で健康診断が行われます。';

        Edit2.Text := '無料です。';

      end

    else

      begin

        Edit1.Text := 'ストレスを溜めない生活を心掛けましょう。';

        Edit2.Text := '体を大切に。';

      end

  ;

end;

 さて、if (    = True )文では、= Trueを省略してもよいことになっています。 試しに = Trueを省略して実行してみましょう。うまく動きましたか?

 

【練習問題】

 【基礎課題4-1-1】のプログラムでも、= True を省略して実行してみましょう。

テキスト ボックス: コラム  if文の書式

 上で述べた通り、if文では次の2つの書き方は全く同じ意味を持ちます。
(1) if (条件式 = True)      (2) if (条件式)
ここに、条件式とは、(SpinEditSum.Value >=6)などのような不等式(あるいは等式)です。しかし、if文で使用するのは不等式などの条件式だけではありません。この点についてもう少し説明しておきましょう。実は、if文の一般的な書き方は次のようになります。
(3) if (論理式)
ここに論理式とは、(条件式=True)のように、それが成り立つか否か、つまり真(True)あるいは偽(False)のいずれかの値を持つ式のことを意味します。さらにDelphiでは、条件式も論理式とみなします。そこで、(1)と(2)はいずれも一般式(3)の特別な形であることが分かるでしょう。
ところで、チェックボックス・コンポーネントのcheckedプロパティはTrueあるいはFalseのいずれかの値を持ちますから、これも論理式の一種と考えられます。そこで、
  if (CheckBoxDoctor.Checked)
と書くことができます。しかし、このように書くと戸惑う学生がいたので、ここでは、
  if (CheckBoxDoctor.Checked = True)
と明示的に記述する様にしました。本テキストでは、以下、=Trueを付けますが、この意味を理解した上で、各自が = True を省略するのは構いません。(通常のテキストでは省略されています。)
 

 

 

 



【基礎課題 4-1-2

次のようなフォームを持つプログラムを作って下さい。

主なコンポーネントのNameプロパティは、次のようにして下さい。

コンポーネント名

Name

スピンエディット

SpinEditOld

ボタン「入力完了」

ButtonEnter

上のエディット

Edit1

下のエディット

Edit2

 

 

 

 

 

 

 

 

年齢を入力してから「入力完了」ボタンを押すと、     2つのメッセージが表示される。

      


年齢とメッセージの対応は、次の表にしたがってください。

年齢

メッセージ

20歳以上

あなたは成年ですね。あなたには選挙権があります。

19歳以下

あなたは未成年ですね。あなたには選挙権がありません。

下の下線部を埋めて、プログラムを完成させて下さい。


 

procedure TForm1.ButtonEnterClick(Sender: TObject);
begin
  if ((SpinEditOld.Value             ) = True)
    then
      begin
                                                
                                                
      end
    else
      begin
                                                
                                                
      end
  ;

【練習問題】

新しいコンポーネント「ラジオボタン」の使い方を覚えましょう。

コンポーネントパレットからラジオボタンのアイコンを選んで、フォーム上に3つ貼って下さい。

      

プログラムを実行する前に、以下の動作を確認してください。

1.  RadioButton1のChekedプロパティの値をTrueにして下さい。

2.  RadioButton2のChekedプロパティの値をTrueにして下さい。

3.  RadioButton1のCheckedプロパティの値を確認して下さい。TrueおよびFalseのどちらになっていますか?

 

次に、プログラムを実行して、ラジオボタンを自由にクリックして下さい。


ラジオボタンはどういうはたらきをするコンポーネントか、下に書いて下さい。

 

 

                                                           

 


【基礎課題 4-1-3

次のようなフォームを持つプログラムを作って下さい。

コラム

左の「ようこそいらっしゃいました。」と「性別をチェックして下さい。」は、 2つのラベルを用いて表現しています。

実は、一つのラベルに複数行のメッセージを表示させることもできます。それには、ラベルコンポーネントの「WordWrap」プロパティを「True」にすればよいのです。こうすると、指定したラベルコンポーネントの幅にメッセージが収まりきれない場合、自動的に折り返されます。つまり、ラベル幅に収まるように複数行表示してくれます。

しかし、最初から2行に分けてメッセージを表示させたい場合は、2つのラベルを用いた方が便利です。

 

 

 

 

 

プログラムの動作内容は以下の通りです。 

 

実行してから性別をチェックしてボタンを押すと、下のように2つのメッセージが表示される。

 

 

チェック項目とメッセージの対応は、次の表にしたがって下さい。

チェック項目

メッセージ

女性

あなたは女性ですね。右側の階段をお上り下さい。

男性

あなたは男性ですね。左側の階段をお上り下さい。

【基礎課題 4-1-4】
次のようなフォームを持つプログラムを作って下さい。

コンポーネント名

Name

ラジオボタン「女性」

RadioButtonF

ラジオボタン「男性」

RadioButtonM

ボタン「OK」

ButtonOK

チェックボックス「18歳以上」

CheckBoxAdult

主なコンポーネントのNameプロパティは、
次のようにして下さい。

 

 

プログラムの動作内容は次の通りです。

 

性別と年齢をチェックしてから「OK」ボタンを押すと、2つのメッセージが表示される。

 

  

 

性別・年齢の条件とメッセージの対応は、次の表にしたがってください。

性別・年齢

メッセージ

女性で、かつ、18歳以上

あなたは入会資格があります。どうぞお入り下さい。

それ以外

あなたは入会資格がありません。残念ですがお帰り下さい。

 

 

注意 「女性で、かつ、18歳以上」つまり、
RadioButtonFがチェックされていて、かつCheckBoxAdultがチェックされている」
ことを、

 

(RadioButtonF.Checked = True) 

and 

(CheckBoxAdult.Checked = True)

 

のように and を用いて表します。

もちろん、先に学習した通り、= Trueを省略して

 

(RadioButtonf.Checked) 

and 

(CheckBoxAdult.Checked)

 

と書くこともできます。ここでは、= Trueを省略せずに見慣れた形のままにしておきます。

 

なお、and の前後の条件式(論理式)には、( )をつけることを忘れないで下さい。(これはDelphiが採用しているPASCAL言語の文法規則なのです。( )をつけ忘れるとエラーになります。)


それでは、下の下線部を埋めて、プログラムを完成させて下さい。

 


procedure TForm1.ButtonOKClick(Sender: TObject);

begin

  if ( (RadioButtonF.Checked = True)

        and

        (CheckBoxAdult.Checked = True) )

    then

      begin

                                                

                                                

      end

    else

      begin

                                                

                                                

      end

  ;



注意 「かつ」ではなく「または」を表したいときは、 
or を使います。

 「女性、または、18歳以上」のとき

(RadioButtonF.Checked = True) 

or 

(CheckBoxAdult.Checked = True)



 

 

 

 

 

 

 

【基礎課題 4-1-5

 

次のようなフォームを持つプログラムを作って下さい。

 

主なコンポーネントのNameプロパティは、
次のようにして下さい。

コンポーネント名

Name

スピンエディット

SpinEditNumber

 

 

 

 

スピンエディットには0〜9までの数しか入りません。それ以外の数を入力できないように、
MinValue プロパティと MaxValue プロパティの値を変更しておいて下さい。


ここで、プログラムを実行し、数を入力してからOKボタンを押したとき、

ようなプログラムを作って下さい。


注意 スピンエディットに入力された値が4以上7以下であることを表すのに、

 

 (4 <= SpinEditNumber.Value <= 7)  = True

 

と書きたくなると思います。しかし、Delphiは、2つの不等号が同時に出てくる文を理解することができません。ですから、

 

( (4 <= SpinEditNumber.Value) = True ) 

and 

( (SpinEditNumber.Value <= 7) = True )

 

のように、条件を二つの部分に分けてから and でつなげて書く必要があります。


【練習問題】

次のようなフォームを持つプログラムを作って下さい。

 

コンポーネントのNameプロパティは、次のようにして下さい。

コンポーネント名

Name

スピンエディット

SpinEditNumber

ボタン「判定」

ButtonHantei

エディット

EditMessage

 

 

 

 

 

 

 

 

0以上の数を入力してボタンを押すと、     0未満の数を入力してボタンを押すと、
「入力した数は0以上です。」と表示し、     「入力した数は0未満です。」と表示する。

 

 

 

 

 

 


「判定」ボタンを押したときの処理は、以下のように書くことができます。

 


procedure TForm1.ButtonHanteiClick(Sender: TObject);

begin

  if ( (SpinEditNumber.Value >= 0) = True )

    then

      begin

        EditMessage.Text:=’入力した数は0以上です。’;

      end

    else

      begin

        EditMessage.Text:=’入力した数は0未満です。’;

      end

  ;

end;

 


しかし、 then のあと、あるいは else のあとに、1つの処理しかしないときは、begin と end を省略して、次のように書くこともできます。

 


procedure TForm1.ButtonHanteiClick(Sender: TObject);

begin

  if ( (SpinEditNumber.Value >= 0) = True )

    then

      EditMessage.Text:=’入力した数は0以上です。

    else

      EditMessage.Text:=’入力した数は0未満です。

こっちはそのまま

 

セミコロンをつけない

 
  ;

end;

 

解説

·         begin と end を省略した場合には、文末のセミコロンをつけてはいけません

If文は

If 〜

then

    処理1

else

    処理2

 

 

一つの文なのです。そこで、例えば「処理1」の末尾に「;」をつけると,そこで文が終わってしまい、そのあとに「else」から新たに文が始まると認識されてしまいます。そしてそのような文はないのでエラーになってしまいます。

·         if文の終わりのセミコロンは、必要です。

 

注意  市販のほとんどのテキストでは,処理文が1つの時には begin end のない形を掲載しています。しかし、実際 のプログラミングの場面では、最初は処理文が1つでも、後に文を加えて複数の文になることがよくあります。その様な場合には再び begin end をつけ加えなければなりませんが、うっかり忘れてしまいやすいものです。そして、もし忘れるとエラーが発生したり思った通りの処理をしてくれなくなったりします。 そこで、処理する文が1つのときでも( begin end がついていてもエラーになるわけではないので)、begin end を消さずに残しておくようにすることを勧めます。


4-2 分岐処理 (2) ―多分岐(if文の中のif文)―

以前つくったストレス度診断プログラムは、もともと、下の分類にしたがって4段階の診断をするものでした。このように、3つ以上の分岐がある場合の処理の仕方を学習しましょう。

チェック数

メッセージ

9〜10

かなりストレスがたまっています。医師による診察を。

6〜8

少しストレスがたまっています。気分転換を。

3〜5

ストレスの兆候がありますが、心配は不要。

0〜2

正常です。

 

【基礎課題 4-2-1

 

【基礎課題4-1-1】のプログラムを新しい名前で保存してから、下のようなフォームのプログラムに作り替えて下さい。


主なコンポーネントのNameプロパティは、次のようにして下さい。

コンポーネント

Name

備考

ボタン「診断」

ButtonShindan

変化なし

スピンエディット「チェック項目数」

SpinEdit

変化なし

チェックボックス「9-10」

CheckBoxHigher

 

チェックボックス「6-8」

CheckBoxHigh

 

チェックボックス「3-5」

CheckBoxLow

 

チェックボックス「0-2」

CheckBoxLower

 

エディット

EditMessage

変化なし

 

 

 

「診断」ボタンを押したときの処理の流れを以下のように考えて、プログラムを書くことにします。


下の空欄を補って、4段階の診断をするプログラムを完成させて下さい。

procedure TForm1.ButtonDiagClick(Sender: TObject);

begin

  if ((SpinEditSum.Value >= 6) = True)

    then

      begin

 


         if ((SpinEditSum.Value >= 9) = True)

           then

             begin

               EditMessage.Text:=’かなりストレスがたまっています。’;

 

             end

           else

             begin

 


               EditMessage.Text:=’少しストレスがたまっています。’;

             end

      end

    else

      begin

 


         if((SpinEditSum.Value >= 3) = True)

           then

             begin

 


               EditMessage.Text:=’ストレスの兆候があります。’;

             end

           else

             begin

 


               EditMessage.Text:=’正常です。’;

             end

      end

  ;

end;

【基礎課題 4-2-2

 

テストの得点を入力してから「成績判定」ボタンを押すと、得点に対応して「優」「良」「可」「不可」の評価をする下のようなプログラムを作って下さい。


得点と成績の対応は、次の表にしたがって下さい。

80点〜100点

60点〜79点

50点〜59点

不可

0点〜49点


また、成績に応じて、それぞれ内容の異なる一行メッセージを出すようにして下さい。
メッセージの内容は自由に考えて下さい。

「テストの得点」欄には100点満点のテストの得点を入力するものとします。スピンエディットの
MaxValueプロパティとMinValueプロパティの値を変えておいて下さい。

 

【基礎課題 4-2-3

【基礎課題 4-2-1】のプログラムのチェック数は、実は「3で割ったときの商」によってメッセージが決まっています。

チェック数

3で割った商

メッセージ

910

3

かなりストレスがたまっています。医師による診察を。

68

2

少しストレスがたまっています。気分転換を。

35

1

ストレスの兆候がありますが、心配は不要。

02

0

正常です。

したがって、予めチェック数を3で割って商を求めておくことによって、if 文をもっと簡単にすることができます。プログラムを次のように変更して下さい。

 

 

procedure TForm1.ButtonDiagClick(Sender: TObject);

var

  q: Integer;

begin

 

  q := SpinEditSum.Value div 3;

 

  if ((q >= 2) = True)

    then

      begin

        if ((q = 3) = True)

          then

            begin

                                                          

                                                                  

            end

          else

            begin

                                                          

                                                                  

            end

        ;

      end

    else

      begin

        if ((q = 1) = True)

          then

            begin

                                                           

                                                                   

            end

          else

            begin

                                                            

                                                                     

            end

        ;

      end

  ;

end;

 

※、上の枠内で「チェック数を3で割った商」qを求めています。商を求める「div」演算子については、3-9節【基礎課題3-9-1】にある説明を参照してください。


4-3 分岐処理 (3) ―2分岐の特殊な形(if then〜文)―

【練習問題】

下のようなフォームのプログラムを作って下さい。


主なコンポーネントのNameプロパティは、次のようにして下さい。

コンポーネント

Name

チェックボックス「賛成します」

CheckBoxSansei

ボタン「投票」

ButtonTouhyou

エディット

EditMessage

スピンエディット「現在の賛成者数」

SpinEditNinzu


プログラムを実行して、「投票」ボタンを押したとき、

ようなプログラムを作ります。

 



このプログラムの流れを図にすると、次のようになります。


プログラムは、次のように書きます。


解説

 

 

 

 

 

 

 

 

 

 

 

【基礎課題 4-3-1

次のようなフォームをもつプログラムを作って下さい。

作成するプログラムは検索処理を模したプログラムです。ただし、現時点では残念ながら検索処理をプログラミングするができません。

 



 

キーワードを入力しないでボタンを押すと、「検索用キーワードを入力してください。」と警告し、 
 

 

 

 

キーワードを入力してボタンを押すと
何もしない。

 

 

 

 

Ø        このプログラムでは、一度警告メッセージが出てしまうと、それ以降は(例えキーワードを入力して[検索]ボタンを押しても)警告が消えてくれません。本来は、キーワードを入力してボタンを押すと、その警告は消えるべきですね。その改良については次章5-13で取り扱います。

 

 

 


4-4 分岐処理 (4) −多分岐(case文)−

 

if文は、

に応じて、プログラムの流れを2つに分岐させるものでした。

プログラムの流れを3つ以上に分けなければならないときは、4-2で学習したように、if文の中にさらにif文を書かなければなりません。その結果、プログラムの構造が複雑になってしまいました。


そこで、プログラムの流れを3つ以上に分ける場合に使うと便利な、
case文の使い方を説明します。


【基礎課題 4-2-3】は、case文を使うと次のように書くことができます。

 


procedure TForm1.ButtonDiagClick(Sender: TObject);

var

  q: Integer;

begin

  q := SpinEditSum.Value div 3;

  Case (q) of

    3:

begin

q=3 の時の処理

 
 

 


         end;

    2:

      begin

q=2 の時の処理

 
 

 


         end;

    1:

      begin

q=1 の時の処理

 
 

 


         end;

    0:

      begin

q=0 の時の処理

 
 

 


end;

  end;

end;


さらにcase文では、次のように変数の範囲を直接指定することもできます。

 


procedure TForm1.ButtonDiagClick(Sender: TObject);

begin

  Case (SpinEditSum.Value) of

    9..10:

begin

SpinEditSum.Valueの値が9〜10の時の処理

 
 

 


         end;

    6..8:

      begin

SpinEditSum.Valueの値が6〜8の時の処理

 
 

 


         end;

    3..5:

      begin

SpinEditSum.Valueの値が3〜5の時の処理

 
 

 


         end;

    0..2:

      begin

SpinEditSum.Valueの値が0〜2の時の処理

 
 

 


end;

  end;

end;

 

 

 

次ページに、case文の書式(記述の仕方)をまとめておきましょう。

 

  case 変数名 of
    変数の値の範囲
      begin
        変数の値がその範囲にあるときの処理1;   
        変数の値がその範囲にあるときの処理2;
        変数の値がその範囲にあるときの処理3;
           ・
           ・
           ・
      end;
    変数の値の範囲
      begin
        変数の値がその範囲にあるときの処理1;
        変数の値がその範囲にあるときの処理2;
        変数の値がその範囲にあるときの処理3;
           ・
           ・
           ・
      end;
    変数の値の範囲
      begin
        変数の値がその範囲にあるときの処理1;
        変数の値がその範囲にあるときの処理2;
        変数の値がその範囲にあるときの処理3;
           ・
           ・
           ・
      end;
    ・
    ・
    ・
  end;

< case文の書き方 >

 

解説

 

 

 

【基礎課題 4-4-1

【基礎課題 4-2-1】を、case文を使って作り直してください。

 

 

【基礎課題 4-4-2

【基礎課題 4-2-2】を、case文を使って作り直してください。

「診断」ボタンを押したときの処理

  case 変数名 of
    変数の値の範囲
      begin
        変数の値がその範囲にあるときの処理1;
        変数の値がその範囲にあるときの処理2;
           ・
           ・
      end;
    変数の値の範囲
      begin
        変数の値がその範囲にあるときの処理1;
        変数の値がその範囲にあるときの処理2;
           ・
           ・
      end;
    変数の値の範囲
      begin
        変数の値がその範囲にあるときの処理1;
        変数の値がその範囲にあるときの処理2;
           ・
           ・
      end;
       ・
       ・
    else
      begin
        変数の値が今までのどの範囲にもないときの処理1;   
        変数の値が今までのどの範囲にもないときの処理2;
           ・
           ・
      end;
  end;  ( case文の終わりを表す)

 

 

 

 

 

case文には、else を使った特殊な例があります。一番下の「変数の値の範囲」を else と書いて、「今までに指定した範囲以外」という意味を表すことができます。

 

必要がない場合はelse文以下(   で囲まれた部分)を省略する事ができます。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

【応用課題 4-4-A

年齢を入力してからボタンを押すと、次の料金表にしたがって入場料金を表示するプログラムを、else をともなったcase文を利用して作って下さい。

 

料金表

年齢

入場料金

6歳以上12歳以下

500円

13歳以上65歳以下

1000円

それ以外(5歳以下または66歳以上)

無料


4-5 繰り返し処理 (1) ―累乗―

スーパーファミコンは 16 ビット、PlayStation は 32 ビット、NINTENDO 64 は 64 ビット、さらにはこのコンピュータのメモリは 64 MB あるいは 128 MB 等々、コンピュータ関係のもので出てくる数には決まった数が多いですね。これらの数は、2×2×2×…×2 の形で求められる、コンピュータにとって“きりのいい”数なのです。

 

【練習問題】

下の表を埋めましょう。

 

 

2の個数

(計算結果)

21

2

1

2

22

2×2

2

4

23

2×2×2

3

 

24

2×2×2×2

4

 

25

2×2×2×2×2

5

 

26

2×2×2×2×2×2

6

 

27

2×2×2×2×2×2×2

7

 

28

2×2×2×2×2×2×2×2

8

 

29

2×2×2×2×2×2×2×2×2

9

 

210

2×2×2×2×2×2×2×2×2×2

10

 

 

2×2×2×2×2 のように、ある数 a を b 個かけることを累乗といいます。

2×2×2×2×2 のことを、2を5個書く代わりに「25」と書いて「2の5乗」と読みます。


【基礎課題 4-5-1】

 

2倍」ボタンを押したら

左の値が2倍になり、さらにもう1度「2倍」ボタンを押したら

さらに2倍になり、ボタンを押すごとに値がどんどん2倍になっていく、というプログラムを作りましょう。

まずは、フォーム上にコンポーネントを次のように配置してください。

コンポーネント

Name

左のスピンエディット

SpinEditNumber

右のボタン

ButtonDouble

注意 SpinEditNumber.Value の初期値を 1 にしておいてください。

次の空欄を埋めてプログラムを完成させて下さい。

 

procedure TForm1.ButtonDoubleClick(Sender: TObject);

begin

    SpinEditNumber.Value :=                         ;

end;


【練習問題】

このプログラムを使えば、25 の値を調べたいときも「2倍」ボタンを5回押すだけで求められます。では、このプログラムをもっと改良して、ボタンを1度押すだけで 25 が求められるようにできないでしょうか。

これはそれほど難しくありません。ボタンを押したときに今までの5回分の動作をすればよいのですから、

procedure TForm1.ButtonDoubleClick(Sender: TObject);

begin

  SpinEditNumber.Value := SpinEditNumber.Value * 2;

  SpinEditNumber.Value := SpinEditNumber.Value * 2;

  SpinEditNumber.Value := SpinEditNumber.Value * 2;

  SpinEditNumber.Value := SpinEditNumber.Value * 2;

  SpinEditNumber.Value := SpinEditNumber.Value * 2;

end;

となります。実行して動作を確認してみましょう。

 

【基礎課題 4-5-2

ボタンを1度押すだけで 215 が求められるよう、プログラムを改変して下さい。

procedure TForm1.ButtonDoubleClick(Sender: TObject);

begin

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

end;

 


4-6 繰り返し処理 (2) −for 文の導入―

【基礎課題 4-6-1

何乗の値を計算したいか (ここでは 3 乗) を入力して「計算」ボタンを押すと

その値を計算してくれる、というプログラムを作りましょう。

 

コンポーネント

Name

左のスピンエディット

SpinEditJo

右のスピンエディット

SpinEditResult

下のボタン

ButtonCalc

まずはつぎのようにフォームを作ってください。

注意 SpinEditResult.Value を 1 にしておくのを忘れないようにしましょう。

このプログラムでは、「何回2倍するか」はプログラム実行後にユーザが決めるので、今までのようにプログラム実行前に

procedure TForm1.ButtonDoubleClick(Sender: TObject);

begin

  SpinEditResult.Value := SpinEditResult.Value * 2;

  SpinEditResult.Value := SpinEditResult.Value * 2;

  SpinEditResult.Value := SpinEditResult.Value * 2;

 

         続く

 

  SpinEditResult.Value := SpinEditResult.Value * 2;

end;

とあらかじめ決まった回数だけ書いておくことはできません。

 

 

そこで、同じ動作を繰り返させる 「for 文」という命令を使います。プログラムを次のように書いてください。

実行して動作を確認しましょう。この for 文は、下のような構造になっています。

forカウント用変数(カウンタ:ここでは i := 初期値(ここでは 1) toカウンタの終値 do
  begin
    繰り返し処理1;
    繰り返し処理2;
      ・
      ・
  end;

for文は通常、決まった回数の繰り返しに用います。下の左右のプログラムは全く同じ動作をします。

procedureTForm1.ButtonDoubleClick(Sender: TObject);
begin
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
  SpinEdit1.Value := SpinEdit1.Value * 2;
end;
procedure TForm1.ButtonDoubleClick(Sender: TObject);
var
  i: Integer;
begin
  fori := 1to15do
    begin
      SpinEdit1.Value := SpinEdit1.Value * 2;
    end;
end;

 

コラム

 

forカウント用変数 := 初期値 to繰り返し回数 do

  begin

    繰り返し処理;

  end;

というように、繰り返し処理が1つしかない for 文は、if 文の場合と同様に、beginend を省略して次のように書くことが出来ます。

 

forカウント用変数 := 初期値 to繰り返し回数 do

  繰り返し処理;

 

しかし、この書き方は、後で繰り返し処理を増やしたくなった場合に beginend を付け忘れる可能性があり、実際これまでもそのようなエラーは(本演習において)頻繁に見受けられました。そこで、たとえ処理が1つでも常に beginend をつけることを勧めます。

 

【基礎課題 4-6-2】

先ほどのプログラムを改変して、

数値を入れたら (この例では 3)

3の累乗が求められるプログラムを作ってください。

 

 

 

 

 

【基礎課題 4-6-3】

かけ算は、足し算の繰り返しと考えることができます。例えば、2×5は、「2を足す」ということを5回繰り返すことです。

このように考えると、かけ算の記号「*」を使わずに、for文を使ってかけ算の答を求めることができます。

前のページのプログラムを改変して

数値を入れたら (この場合は 6)

4+4+4++4 を求めるプログラムを、for 文を使って作って下さい(ただし、プログラムの中でかけ算「*」を使ってはいけません。)。

 

【基礎課題 4-6-4】

怒りの度合いを数値で入力し「怒る」ボタンを押すと

その度合いに応じて「こらこら」と表示するプログラムを作りなさい。

  • 度合いが1なら「こら」
  • 度合いが2なら「こらこら」
  • 度合いが3なら「こらこらこら」

(以下同様)

ヒント ‘こら’という文字列を、指定回数だけ連結すれば良いのです。文字列の連結がよく分からない人は、3-11を参照してください。

 


4-7 繰り返し処理 (3) ―for文の流れの観察(デバッガ利用)―

【練習問題】

【基礎課題 4-6-1】で作った「2 の累乗」プログラムで「計算」ボタンを押したときのプログラムが動作する様子を1行ずつ順に追いかけてみましょう。

まずは、ボタンが押されたら一旦プログラムを止めるため、「ブレークポイント (“一時停止”の標識) 」をおきます。コードエディタの次の部分をクリックしてください。

 

すると、ブレークポイント (小さな赤丸) が現れます。

 

それでは実行してみましょう。下のように入力して「計算」ボタンを押すと…

ブレークポイントの隣に小さな緑の矢印が現れます。これは、「プログラムをここから再開します」という標識です。ここで、[F8]キーを押すと (または「実行」→「ステップ実行」を選ぶと)

プログラムが1行実行されて、緑の矢印が次の行に移ります。

以下同じ要領で[F8]を押すと、1行ずつ処理が実行され、指定した繰り返しの回数分の処理が終了すると、下の様に、緑色の矢印が最後の「end;」まで来るはずです。

ここで、Delphiのメニューから「実行」→「プログラムの終了」を選択してプログラムの実行を終了させましょう。

さて、今度は SpinEditResult.Value の値を確認しながら1行ずつ実行させてみましょう。

再び、プログラムを実行させて、下のような状態で「計算」ボタンを押しましょう。

すると、先ほど同様、緑の矢印が表れましたね。

ここで、マウスを使って、下のようにSpinEditResult.Value を選択してください (左ボタンを押しながら領域をなぞってください。左ボタンを離すと選択が完了します。)。

 

今選択した部分の上で右クリックするといくつかのメニューが現れるので、その中から次ページのように、「デバッグ」「カーソル位置の単語を監視」を選びます

 

 

 

 

 

 

 

 

 

 

すると、「監視式一覧」というウィンドウが現れ、SpinEditResult.Value の値を常に表示してくれるようになります。

同様に、i の値も監視しましょう。

今は「参照できない値です。」と表示されていますが、「F8」を押していくとそのうち正しく表示されます。

 

このままどんどん「F8」を押し、SpinEditResult.Valuei の値の変化を調べて下の表を埋めましょう。

 

SpinEditResult.Value

1

1

 

 

 

 

i

参照できない

 

 

 

 

 


4-8 繰り返し処理 (4) ―カウント用変数を使ったプログラム―

i は何回目の繰り返しかを数える変数です。これを文法用語では「制御変数」と呼びますが、ここでは分かりやすく「カウント用変数(カウンタ)」と呼びましょう。beginend の間を1回実行するたびに、iは1つずつ増えます。この性質を利用すると、自然数の和などを簡単に求めることができます

【基礎課題 4-8-1】

下のようなフォームのプログラムを作ってください

コンポーネント

Name

上のスピンエディット

SpinEditResult

下のボタン

ButtonCalc

最初の値は「0」にしておいて下さい。

 

このプログラムで 1+2+3+4+5 を計算させて結果を表示させます。下線部を埋めてください。

procedure TForm1.ButtonCalcClick(Sender: TObject);

var

  i: Integer;

begin

  for i := 1 to 5 do

    begin

      SpinEditResult.Value := SpinEditResult.Value +        ;

    end;

 end;

任意の数を指定できるようにする

 
 


【基礎課題 4-8-2】

上のプログラムを改良して、5 までではなく任意の数までの和を求める (どこまで足すかを指定できる) プログラムを、for 文を使って作って下さい。

 

【基礎課題 4-8-3】

2+4+6+8+ を計算するプログラムを、for 文を使って作って下さい。

【基礎課題 4-8-4】

1+3+5+7+・・・ を計算するプログラムを、for 文を使って作って下さい。

最初は「0」にしておきます。

 

 

【応用課題 4-8-A】

左のピラミッドは、1番上の段は石が 12=1 個、上から2段目は 22=4 個、上から3段目は 32=9 個です。このピラミッドが5段になったときの石の個数を求めるプログラムを作って下さい。

また、このプログラムを改良して、

最初は「0」にしておきます。

 
ピラミッドの段数を入力して「計算」ボタンを押したら

答えを出力するプログラムを作って下さい。

1

2

3

4

5

6

7

8

9

2

4

6

8

10

12

14

16

18

3

6

9

12

15

18

21

24

27

4

8

12

16

20

24

28

32

36

5

10

15

20

25

30

35

40

45

6

12

18

24

30

36

42

48

54

7

14

21

28

35

42

49

56

63

8

16

24

32

40

48

56

64

72

9

18

27

36

45

54

63

72

81

 

【応用課題 4-8-B】

右は、かけ算の九九表です。この全ての数の合計を求めるプログラムを作って下さい。

 

ヒント 例えば、1行目(1番上の横の並び)の和を求めることはすでにできるはずです。これに、2行目、3行目の和を順次加えて行けばよいのです。

すると・・・

最終的には「4-2 if文の中のif文」のように「for文の中のfor文」という形になるはずです。

これができたら大したもの!


4-9 繰り返し処理 (5) ―回数が定まっていない繰り返し―

1分間で2個に分裂するバクテリアが、今1個あります。このバクテリアが10000個以上になるのは何分後でしょうか。

この問題を解くため、

1分だけ経過」ボタンを押すと

1分経過してバクテリアが2倍になり、さらに「1分だけ経過」ボタンを押していくと

バクテリアがどんどん増えていき、いつかは10000個を越える、というプログラムを作ります。

 

 

 

 

 

 

 

 

【基礎課題 4-9-1

まずは次のようにフォームにコンポーネントを配置してください。

コンポーネント

Name

上のスピンエディット

SpinEditMinute

中のスピンエディット

SpinEditBact

下のボタン

ButtonCalc

最初は「1」にしておきます。

 

 

ボタンを押したときの動作をプログラミングします。下線部には何が入りますか?

procedure TForm1.ButtonCalcClick(Sender: TObject);

begin

  SpinEditMinute.Value :=                         ;

  SpinEditBact.Value :=                         ;

end;

 

また、バクテリアが10000個以上になるのは何分後でしょうか?

        分後


4-10 繰り返し処理 (6)  ―While文の導入―

前のプログラムでは、何度もボタンを押していくとそのうち答えが求まります。でも、ボタンを1回押すだけで答えが求まるプログラムにしたいですね。

何回もボタンを押すことは、for 文ででてきた「繰り返し」と呼ばれる操作 (作業) です。ですから、まずは for 文を使ってボタンを1回押すだけのプログラムを考えてみましょう。プログラムは次のようになります。

procedure TForm1.ButtonCalcClick(Sender: TObject);

var

  i: Integer;

begin

  for i := 1 to          do

    begin

      SpinEditMinute.Value := SpinEditMinute.Value + 1;

      SpinEditBact.Value := SpinEditBact.Value * 2;

    end;

end;

しかし、困りました。「何回繰り返すか」を指示する下線部に何と書いていのか、わからないのです。

【練習問題】

for 文は、回数が決まっている繰り返しにしか使えないのです。回数が決まっていない繰り返しには、「while文」を使います。プログラムを次のように変更してください。

procedure TForm1.ButtonCalcClick(Sender: TObject);

begin

  while ( (SpinEditBact.Value < 10000) = True ) do

    begin

      SpinEditMinute.Value := SpinEditMinute.Value + 1;

      SpinEditBact.Value := SpinEditBact.Value * 2;

    end;

end;

 

※ 上の記述でwhileにおける条件式の部分は、if文のときと同じく = True を省略しても構いません。したがって、次のように書いても構いません。

while (SpinEditBact.Value < 10000) 

あるいは 

while条件  do
  begin
    繰り返し処理1;
    繰り返し処理2;
      ・
            ・
  end;

while SpinEditBact.Value < 10000

 

 

while 文は、「条件が成立している間は処理を繰り返す」という制御を行い、右のように書きます。

 

 

プログラムを実行して、結果を確かめてみましょう。ちゃんと「14分」という答が出ましたか?

条件によって処理が変わるという点で if 文と while 文は似ていますが、if 文は条件が成立してもしなくても1回きり、while 文は条件が成立している間何度でも繰り返す点が違います。

if文>

                                 <while文>

 

 

 

 

 

 

 

 

 

 

while条件 do

  begin

    繰り返し処理;

  end;

というように、繰り返し処理が1つしかない while 文は、if 文の場合と同様に、beginend; を省略して次のように書くことが出来ます。

while条件 do

  繰り返し処理;

しかし、この書き方では、後で繰り返し処理を増やしたくなった場合に beginend; を付け忘れる可能性があります。これまで同様、たとえ処理が1つでも常に beginend; をつけることを勧めます。

 

【基礎課題 4-10-1】

1+2+3+4+… と足していくと、はじめて 10000 を超えるのはどこまで足したときでしょうか? プログラムを使って求めて下さい。(数列の和の公式は使わないで下さい。)

 

【応用課題 4-10-A】

1年間に 5% の利子がつく (つまり預金が 1.05 倍になる) 口座があります(今となっては夢のような利率ですが・・・)。この口座に10000円を預けておくと、何年後に30000円以上になるでしょうか? 右のようなプログラムを作って答を求めて下さい。

ヒント 端数の切り捨てにはTrunc( )を用いてください。 

例: Trunc(1.3) →1、 Trunc(1.9) → 1、 等々。