[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

コンピュータIIIB(Javaアルゴリズム)第2回

目次
2.1 制御構造
2.2 条件文
2.2.1 基本的な条件文
2.2.2 switch文
2.3 繰返し文
2.3.1 基本的な繰返し文
2.3.2 do-while文
2.4 分岐文
2.4.1 分岐とは
2.4.2 break文
2.4.3 continue文
2.5 制御構造の例
2.6 演習2
2.7 レポート課題
2.8 参考文献
索引
break文   case文   continue文   do-while文   for文   if-else文   if文   return文   switch文   while文   繰返し文   ジャンプ   条件文   制御構造   分岐   ループ  

2.1 制御構造

プログラムの基本形は、文を並べたものです。 このようなプログラムを実行すると、コンピュータは文の順序に従って動きます。 コンピュータの動きを変えるには、 制御構造 ( control structure )を利用します。 制御構造を表す文には、条件文や繰返し文などがあります。


2.2 条件文

2.2.1 基本的な条件文

条件文 ( conditional statement )は、条件が成り立つかどうかによって実行する文が変わるものです。 基本的な条件文には、 if 文と if - else 文があります。

if文 の形式は

if (条件式) {
    文の並び
}

です。 これで、条件式の値が true ならば文の並びが実行されます。

if-else文 の形式は

if (条件式) {
    文の並び1
} else {
    文の並び2
}

です。 これで、条件式の値が true ならば文の並び1が実行され、 false ならば文の並び2が実行されます。

if - else 文を多重にするには、

if (条件式1) {
    文の並び1
} else if (条件式2) {
    文の並び2
} else {
    文の並び3
}

のように書きます。

2.2.2 switch文

「もし式の値が1ならば何々をし、2ならば何々をし、…」という制御構造は、それなりに使われます。 Java言語では、このような構造のために、 switch 文が用意されています。

switch文 は、 case文 を伴い、次のように書きます。

switch (整数式) {
    case 整数1: 文の並び1 break;
    ...
    default: 文の並び* break;
}

これで、整数式の値が整数1ならば文の並び1が実行され、…、どれでもないならば文の並び*が実行されます。

1つの switch 文の中の case 文は、整数がすべて異なるようにします。 また、 case 文の並びの最後には、どれでもない場合を表す default を書きます。 それぞれの case 文の最後には、 break を書きます。

例えば、配列に格納されたゴルフのスコアを、数ではなく「パー」や「バーディー」のように出力するプログラムは、次のようになります。

/*  1*/ class SwitchTest {
/*  2*/     public static void main (String[] args) {
/*  3*/         int i;
/*  4*/         int[] a = {0, 2, -2, 4, 1, 1, 3, 0, -1};
/*  5*/         for (i = 0; i < a.length; i++) {
/*  6*/             switch (a[i]) {
/*  7*/                 case -2: System.out.println("イーグル"); break;
/*  8*/                 case -1: System.out.println("バーディー"); break;
/*  9*/                 case 0: System.out.println("パー"); break;
/* 10*/                 case 1: System.out.println("ボギー"); break;
/* 11*/                 case 2: System.out.println("ダブル・ボギー"); break;
/* 12*/                 case 3: System.out.println("トリプル・ボギー"); break;
/* 13*/                 default: System.out.println(a[i]); break;
/* 14*/             }
/* 15*/         }
/* 16*/     }
/* 17*/ }
asiaa1:~/comp3b b08a001$ java SwitchTest
パー
ダブル・ボギー
イーグル
4
ボギー
ボギー
トリプル・ボギー
パー
バーディー
asiaa1:~/comp3b b08a001$

もちろん、 switch 文を使わなくても、 if - else 文を使えば同じことができます。 ただし、プログラムは多少長くなります。 以下のプログラム(部分)と比較してください。

if (a[i] == -2) {
    System.out.println("イーグル");
} else if (a[i] == -1) {
    ...
} else {
    System.out.println(a[i]);
}

2.3 繰返し文

2.3.1 基本的な繰返し文

繰返し文 ( repetitive statement ) は、文を何度か繰り返し実行するものです。 繰返しは ループ ( loop ) とも呼ばれます。 基本的な繰返し文には、 while 文と for 文があります。

while文 の形式は

while (条件式) {
    文の並び
}

です。 これで、条件式の値が true である限り、文の並びが繰り返し実行されます。

for文 の形式は

for (文1; 条件式; 文2) {
    文の並び
}

です。 これは、

文1
while (条件式) {
    文の並び
    文2
}

と同じ意味です。

2.3.2 do-while文

while 文と似たものに、 do - while 文があります。 これは、条件式を確認してから文の並びを実行するのではなく、文の並びを実行してから条件式を確認するものです。

do-while文 の形式は、次の通りです。

do {
    文の並び
} while (条件式);

これは、

文の並び
while (条件式) {
    文の並び
}

と同じ意味です。

while 文がその中身を一度も実行しないかもしれないのに対して、 do - while 文はその中身を必ず一度は実行します。 条件式の値に関わらず、1回以上繰り返す場合は、 do - while 文を使います。

例えば、長さが0ではない配列の要素を出力するプログラムは、次のように書けます。 ただし、配列の長さが0の場合はエラーになりますので、あまりよいプログラムではありません。

/*  1*/ class DoWhileTest {
/*  2*/     public static void main (String[] args) {
/*  3*/         int i;
/*  4*/         int[] a = {10, 20, 30, 40, 50};
/*  5*/         i = 0;
/*  6*/         do {
/*  7*/             System.out.println(a[i]);
/*  8*/             i++;
/*  9*/         } while (i < a.length);
/* 10*/     }
/* 11*/ }
asiaa1:~/comp3b b08a001$ java DoWhileTest
10
20
30
40
50
asiaa1:~/comp3b b08a001$

2.4 分岐文

2.4.1 分岐とは

プログラムの文を順番に実行せず、他の所に移動する制御のことを、 分岐 ( branch ) または ジャンプ ( jump ) と言います。

例えば、 return文 は分岐文の一種です。 メソッドの実行中に return 文があると、メソッドの途中でも実行が終了し、呼出し側に制御が戻ります。

2.4.2 break文

break文 は、繰返しを終了する分岐文です。 具体的には、繰返し文 while , do - while , for の実行中に break 文があると、繰返しの途中でも実行が終了し、繰返し文の次に制御が移ります。

break 文は、例えば要素の探索に役立ちます。 配列の中に0以外の数があるかどうかを確認する場合、もし0以外の数が見つかったら、残りの要素を確認する必要はありません。 そこで、 for 文を用いて配列要素を一つずつ確認し、もし0以外の数だったら、 break 文で繰返しを終了するというプログラムが書けます。

/*  1*/ class BreakTest {
/*  2*/     public static void main (String[] args) {
/*  3*/         int i;
/*  4*/         int[] a = {0, 0, 0, 40, 0};
/*  5*/         for (i = 0; i < a.length; i++) {
/*  6*/             if (a[i] != 0) {
/*  7*/                 break;
/*  8*/             }
/*  9*/         }
/* 10*/         if (i < a.length) {
/* 11*/             System.out.println("見つかりました。");
/* 12*/         } else {
/* 13*/             System.out.println("見つかりません。");
/* 14*/         }
/* 15*/     }
/* 16*/ }
asiaa1:~/comp3b b08a001$ java BreakTest
見つかりました。
asiaa1:~/comp3b b08a001$

break 文を利用した場合、(見つからなくて)条件式で繰返しが終了したのか、(見つかって) break 文で繰返しが終了したのかが分かりません。 上記のプログラムでは、ループ制御変数 i が配列の途中を指しているかどうかで判定しています。 以下のプログラムでは、論理型の変数 found を用意し、見つかったら found の値を変えることで区別します。

/*  1*/ class BreakTest2 {
/*  2*/     public static void main (String[] args) {
/*  3*/         int i;
/*  4*/         int[] a = {0, 0, 0, 40, 0};
/*  5*/         boolean found = false;
/*  6*/         for (i = 0; i < a.length; i++) {
/*  7*/             if (a[i] != 0) {
/*  8*/                 found = true;
/*  9*/                 break;
/* 10*/             }
/* 11*/         }
/* 12*/         if (found) {
/* 13*/             System.out.println("見つかりました。");
/* 14*/         } else {
/* 15*/             System.out.println("見つかりません。");
/* 16*/         }
/* 17*/     }
/* 18*/ }

2.4.3 continue文

continue文 は、繰返しを完全に終了するのではなく、繰返しを一回だけ終了する分岐文です。 具体的には、繰返し文 while , do - while , for の実行中に continue 文があると、繰返しの途中でもその回が終了し、次の回のために繰返し文の条件式に制御が移ります。

continue 文は、例えば一部の要素を無視するときに役立ちます。 配列の要素を出力するが、0は無視する場合、もし0が見つかったら、それに対する処理は必要はありません。 このことを continue 文で表すと、次のようになります。

/*  1*/ class ContinueTest {
/*  2*/     public static void main (String[] args) {
/*  3*/         int i;
/*  4*/         int[] a = {10, 20, 30, 0, 50};
/*  5*/         for (i = 0; i < a.length; i++) {
/*  6*/             if (a[i] == 0) {
/*  7*/                 continue;
/*  8*/             }
/*  9*/             System.out.println(a[i]);
/* 10*/         }
/* 11*/     }
/* 12*/ }
asiaa1:~/comp3b b08a001 java ContinueTest
10
20
30
50
asiaa1:~/comp3b b08a001$

2.5 制御構造の例

ここで、制御構造の例として、配列を処理するプログラムを紹介します。

以下のプログラムは、配列要素が同じ値で連続しているとき、その2番目以降を0に置き換えるものです。 プログラムで与えた配列は、

{1, 1, 1, 2, 3, 3, 3, 3, 2, 2}

です。 プログラムのポイントは、配列要素の値を変数 val に格納しておき、その後、配列要素と val が違っていれば、 val を更新することです。

/*  1*/ class RunToZero {
/*  2*/     public static void main (String[] args) {
/*  3*/         int i, val = 0;
/*  4*/         int[] a = {1, 1, 1, 2, 3, 3, 3, 3, 2, 2};
/*  5*/         for (i = 0; i < a.length; i++) {
/*  6*/             if ((i == 0) || (a[i] != val)) {
/*  7*/                 val = a[i];
/*  8*/             } else {
/*  9*/                 a[i] = 0;
/* 10*/             }
/* 11*/         }
/* 12*/         for (i = 0; i < a.length; i++) {
/* 13*/             System.out.print(" " + a[i]);
/* 14*/         }
/* 15*/         System.out.println();
/* 16*/     }
/* 17*/ }
asiaa1:~/comp3b b08a001$ java RunToZero
 1 0 0 2 3 0 0 0 2 0
asiaa1:~/comp3b b08a001$

2.6 演習2

上記のプログラムの逆変換を行うプログラムを作成してください。 つまり、配列

{1, 0, 0, 2, 3, 0, 0, 0, 2, 0}

の0を、直前の0でない数に置き換えてください。

asiaa1:~/comp3b b08a001$ java ZeroToRun
 1 1 1 2 3 3 3 3 2 2
asiaa1:~/comp3b b08a001$

2.7 レポート課題

今日の演習2の答案(Javaプログラム)をメールで提出してください。 差出人は学内のメール・アドレス(b08a001@cis.twcu.ac.jpなど)とし、宛先はkonishi@cis.twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(10月3日)を明記してください。


2.8 参考文献


[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

2008年10月3日更新
小西 善二郎 <konishi@cis.twcu.ac.jp>
Copyright (C) 2008 Zenjiro Konishi. All rights reserved.