プログラミング入門(金曜1・2限)講義資料(2008年後期)

プログラミング入門 第3回

前回の復習

繰り返し(while文)

コンピュータは繰り返しが得意と言われています.今度は繰り返しに挑戦してみましょう.

例えば,コンピュータに次の図のようなことをさせたいことがよくあります.

while文はこのようなことを書くための構文です.while文はこんな形をしています.

while (条件) {
    文;
}

while文を使うと,「ある条件が成り立っている間,ある処理を繰り返す」ことができます.

次のプログラムは下の図のように実行されます.

処理1;
while (条件) {
    処理2;
    処理3;
}
処理4;

while文の中を実行することによってそのうち条件が満たされるようにプログラムを書きます.(そうしないと,プログラムの実行が終わりません).

while文を使った繰り返しの方法

繰り返しの回数が予めわかっているならば,繰り返しの回数を変数で数えます.繰り返しの数を数えるために使う変数を,カウンタと呼ぶことがあります.以下は3回繰り返す場合の典型的な例です.

// 0から数えるスタイル
int i = 0;              // 繰り返しの数を数える変数(カウンタ)
while (i < 3) {
    繰り返したいコト;
    i = i + 1;	        // カウンタを増やす
}
System.out.println("i の値は " + i + " です");

i = i + 1 というのは変な気がするかも知れませんが,Java の = は,等しいという意味ではなく,右側の値を左側の変数に代入するという意味なので,これで i の値を 1 増加させることができます.

これは,以下のように実行され,結局「繰り返したいコト」が3回実行されます.

1int i = 0;i に 0 が代入される
2i < 3 ?true なので while 文の中へ進む
3繰り返したいコト;
4i = i + 1;i に 1 が代入される
5i < 3 ?true なので while 文の中へ進む
6繰り返したいコト;
7i = i + 1;i に 2 が代入される
8i < 3 ?true なので while 文の中へ進む
9繰り返したいコト;
10i = i + 1;i に 3 が代入される
11i < 3 ?false なので,while文を終了して次に進む
12System.out.println("i の値は" + i + "です");"i の値は3です" と表示

他にも

// 3から減らしていくスタイル
int i = 3;
while (i > 0) {
    繰り返したいコト;
    i = i - 1;
}
// 1から数えるスタイル
int i = 1;
while (i <= 3) {
    繰り返したいコト;
    i = i + 1;
}

好きなスタイルを使って下さい.

簡単な例

while文を使って,整数の掛け算を * (乗法演算子) を使わずにやってみましょう.x * y は,x を y 回加えることで計算できます.


このファイルをダウンロード ■ UNIX用(EUC版) ■ Windows用(SJIS版)
(上のどちらかのリンクを右ボタンでクリックして「リンク先を名前をつけて保存」して下さい)

// 乗算演算子(*)を使わずに掛け算してみる

public class Multiple {
    public static void main(String[] arg) {
        System.out.print("x: ");
        int x = Keyboard.intValue();
        System.out.print("y: ");
        int y = Keyboard.intValue();

	// 結果を覚えておく変数を用意して 0 にしておく
        int kekka = 0;

        while (y > 0) {			// この条件が成り立つ間繰り返す
	    // 繰り返したいコト
            kekka = kekka + x;		// 結果に x を足す
            System.out.println("kekka = " + kekka); // 実行観察用の表示
            System.out.println("y = " + y);         // 実行観察用の表示

            y = y - 1;			// y から 1 を引く
        }
        System.out.println("乗算結果は " + kekka + " です");
    }
}


whileの中を一度実行すると,y の値が 1 減るので,そのうち y >0が偽になって,while 文の実行が終わり,結果が表示されます.実際にwhile文の中がy回実行されることを確認してください.

逐次処理条件分岐(if文)繰り返し(while文)の3つがプログラムの基本的な構造になります.どんなに複雑な処理もこの3つを使って書くことができます(理論的には).

演習

キーボードから整数nを入力し,nの階乗(1 * 2 * .... * n) を求めるプログラム Factorial を作って下さい.

結果はかなり大きな数になるので,int型ではなくlong型を使ってください.

考え方

(fact = fact * 1)
fact = fact * 2
fact = fact * 3
...
fact = fact * n

と繰り返し計算すれば良い.while文を使って

fact = fact * i
i = i + 1

を繰り返す.

演習

2つの数A, B(正の整数とする)を入力し,次の方法を使って最大公約数を計算するプログラム(Eucrid)を作ってください.

++ 演算子と -- 演算子

プログラミングでは,1を足したり1を引いたりすることがよくあります.このために,Javaでは簡単な書き方を用意しています.

i++;  // i = i + 1; と同じ
++i;  // i = i + 1; と同じ
i--;  // i = i - 1; と同じ
--i;  // i = i - 1; と同じ

実は i++ と ++i の意味はちょっと違いますが,今は気にしないことにします.どちらも i が 1 増えることは同じです.

繰り返しからの脱出(break文)

次のようなプログラムを考えます.

キーボードから整数を2つ入力し,両者の和を表示するプログラム Wa を作ってください.

ただし,何度も計算できるように,入力した2つの数が両方とも0だった場合は,プログラムを終了し,そうでなかった場合はまたキーボードから入力して和を計算できるようにしてください.

[... ~/Java/Wa] java Wa
x: 10
y: 15
10 + 15 = 25

x: 2
y: 10
2 + 10 = 12

x: 0
y: 0
終了します
[... ~/Java/Wa] 

こんな感じで書けるでしょう.

// キーボードから整数を2つ入力
while (条件) {
    // 和を計算して表示
    // キーボードから整数を2つ入力
}

でも,この書き方は「キーボードから整数を2つ入力」する処理が2回でてくるのがイマイチですね.次のように書けると便利です.

while (条件) {
    // キーボードから整数を2つ入力
    // 両方とも 0 だったら,while 文を終わる.
    // 和を計算して表示
}
//「終了します」と表示する.

このように,while 文の途中で繰り返しを終了できると都合がよい場合ががよくあります.このために Javaでは break文というものを用意しています.while 文の中で break 文を実行すると,while 文の実行をそこで中断し,while 文の次の文の実行に移ります.

例えば,次のプログラムは下の図のように実行されます.

while (条件1) {
    処理1;
    if (条件2) {
        break;
    }
    処理2;
}

先ほどの例は break 文を使って次のように書くことができます.

while (条件) {
    // キーボードから整数 (x, y) を2つ入力
    // 両方とも 0 だったら,while 文を終わる.
    if (x == 0 && y == 0) {
        break;
    }
    //x と y の和を求めて表示する.
}
//「終了します」と表示する.

無限ループ

さて,今度はwhile文の条件について考えてみましょう.上のプログラムで while 文の実行を続ける条件はどうしたらよいでしょうか?

x と y のチェックをしないといけないと思いましたか? 実はそんなことはしなくてもかまいません.break 文によって while 文を終わるので,while 文のほうではチェックする必要がないのです.

こんなときには,条件に true と書きます.true は常に「成り立っている」を意味する Java の特別な定数です(反対の定数に false があります).while (true) と書くと,while 文の条件は常に成り立つので,break 文を実行しない限り while 文から抜け出すことはありません.このような while 文のことを無限ループと呼ぶことがあります.

while(true) と書いておいて,途中で if 文で条件を判定して適宜 break を実行するようなスタイルはよく使われます.

while (true) {
    // キーボードから整数 (x, y) を2つ入力
    // 両方とも 0 だったら,while 文を終わる.
    if (x == 0 && y == 0) {
        break;
    }
    //x と y の和を求めて表示する.
}
//「終了します」と表示する.

ちなみに,次の2つのプログラムは全く同じ動きをします.

// 普通の書き方
while (条件) {
    ...
}
// 奇妙な(良くない)書き方
while (true) {
    // 条件が成り立たなかったらbreakで抜ける
    if (!(条件)) {
        break;
    }
    ...
}

段階的詳細化

上の例でやったように,プログラムを書くときは,まずおおまかなプログラムの構造を書いてみましょう.日本語で構いません.それをだんだんと詳細化していき,最後にはプログラミング言語 (Java) の記述にします.これを段階的詳細化と言います.プログラム言語でいきなり書き出すよりも簡単に書くことができます.

繰り返しがあるときは,何を繰り返すのか,つまりwhile文の中でやるべきことは何かに注意して詳細化していきます.

詳細化するときに,日本語をコメントとして残すようにしましょう.分かりやすいプログラムを書くことができます.

課題3-1 (駐車料金)

A駐車場の料金は,60分まで1000円,以後,30分毎に600円です.
駐車する時間を分単位で入力し,駐車料金を求めるプログラム ParkingCharge を書いて下さい.while文の練習なので,while文を使うこと.

ヒント: while文の使い方としては,一回繰り返す毎に600円加算するような構造を考える.

考え方

キーボードから駐車時間(park_time)を入力する.
料金(charge)を1000円にセットする.
駐車時間から 60 を引く.
以下を繰り返す.
  駐車時間が 0 より大きいならば,料金に600円加算し,駐車時間から30を引く.
料金を表示する.

課題3-2 (数当てゲーム)

コンピュータが考えた0から99までの整数を人が当てるゲーム Kazuate を作って下さい.

0〜99の範囲で値を入れてください.
Number: 30
30より大きいです
Number: 80
80より小さいです
Number: 40
40より大きいです
Number: 44
4回目で正解!         (このように何回目で正解したかも表示してください)

コンピュータにでたらめな数を考えさせるには,乱数を使います.

Math.random()を使うことで,0以上1未満の範囲の乱数(double型)を発生させることができます.

0〜99までの整数で乱数が欲しいときは,

int answer = (int)(Math.random() * 100);

のように書きます.

Math.random() は実数型(double)の値を返してくるので,それを int 型の変数に代入するためには,(int) というおまじないが必要です.このようにかっこ()の中に型名を書いたものは キャスト演算子 と呼ばれます.これは,値の型を明示的に変換するための演算子です(double 型をint型に,long型をint型に,等)

ヒント: いきなりプログラムを書きはじめるのではなく,プログラムの大まかな構造を考える.繰り返される部分は while を使って書けるはず.

ヒント: 何回目で正解したかの表示は後から付け加えたら良い.

ヒント: 例えば以下のような構造でできる.

while (true) {
    入力
    正解なら break
    大小の表示
}

ヒント: 何回目で正解したかを表示するためには,何回目かを覚えておく変数を作っておき,繰り返す度にその変数を +1 する.

余裕がある人は,入力された値が正解の±1だったときに,惜しい!と表示して下さい.

さらに余裕がある人は,入力された値が正解の±1だったときに,惜しい!と表示して,コンピュータの考えている数を再度計算しなおしてください.