プログラムの基本形は、文を並べたものです。 このようなプログラムを実行すると、コンピュータは文の順序に従って動きます。 コンピュータの動きを変えるには、 制御構造 ( control structure )を利用します。 制御構造を表す文には、条件文や繰返し文などがあります。
条件文
(
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 }
のように書きます。
「もし式の値が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]); }
繰返し文
(
repetitive statement
)
は、文を何度か繰り返し実行するものです。
繰返しは
ループ
(
loop
)
とも呼ばれます。
基本的な繰返し文には、
while
文と
for
文があります。
while
文
の形式は
while (条件式) { 文の並び }
です。
これで、条件式の値が
true
である限り、文の並びが繰り返し実行されます。
for
文
の形式は
for (文1; 条件式; 文2) { 文の並び }
です。 これは、
文1 while (条件式) { 文の並び 文2 }
と同じ意味です。
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$
プログラムの文を順番に実行せず、他の所に移動する制御のことを、 分岐 ( branch ) または ジャンプ ( jump ) と言います。
例えば、
return
文
は分岐文の一種です。
メソッドの実行中に
return
文があると、メソッドの途中でも実行が終了し、呼出し側に制御が戻ります。
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*/ }
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番目以降を0に置き換えるものです。 プログラムで与えた配列は、
です。 プログラムのポイントは、配列要素の値を変数 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$
上記のプログラムの逆変換を行うプログラムを作成してください。 つまり、配列
の0を、直前の0でない数に置き換えてください。
asiaa1:~/comp3b b08a001$ java ZeroToRun 1 1 1 2 3 3 3 3 2 2 asiaa1:~/comp3b b08a001$
今日の演習2の答案(Javaプログラム)をメールで提出してください。 差出人は学内のメール・アドレス(b08a001@cis.twcu.ac.jpなど)とし、宛先はkonishi@cis.twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(10月3日)を明記してください。