制御構造: 繰り返し構文

繰り返し構文は、C言語と同じ使い方ができる。一部機能が拡張されている。


for文による繰り返し

繰り返し何かの処理を行わせるときに使う。

for   ( 初期化式 ; 条件式 ; 変化式 )   {

     処理

}

初期化式
繰り返しを始める前に必ず1回だけ実行される。
条件式
「処理」を1回始める前に毎回実行される。
式の値がtrueなら繰り返しを続けるが、falseなら繰り返しを止めこのfor文から抜ける。
変化式
繰り返しが1回終わる度に実行される。
変数の値を順次変えることが多い。
「条件式」を省略すると繰り返しを抜ける式を指定しないことになる。その場合、ずっと繰り返してしまうので、繰り返しの中で break などにより明示的に繰り返しから抜ける必要がある。

while文による繰り返し

繰り返し何かの処理を行わせるときに使う。

while   ( 条件式 )   {

     処理

}

条件式
「処理」を1回始める前に毎回実行される。
式の値がtrueなら繰り返しを続けるが、falseなら繰り返しを止めこのwhile文から抜ける。
「条件式」は省略できない。

do 〜 while文による繰り返し

繰り返し何かの処理を行わせるときに使う。必ず最低1回は処理される。

do   {

     処理

} while   ( 条件式 );

条件式
「処理」を1回実行した後に毎回実行される。
式の値がtrueなら繰り返しを続けるが、falseなら繰り返しを止めこのdo 〜 while文から抜ける。
「条件式」は省略できない。

continue, breakによる繰り返しの制御

continue
繰り返しの途中で、その繰り返しの回を途中で止めて、繰り返しの次の回を行わせるときに使う。
ただし、次の回に移る前に「条件式」によるチェックが入ることに注意。
Javaでは、
continue ラベル;
として、対象とする繰り返しを指定できる。つまり、一番内側にある繰り返しでなくても、外側の繰り返しの始まり部分に
ラベル:
をつければ、「continue ラベル;」により、その繰り返しに対して continue できる。
break
繰り返しの途中で、その繰り返しの回を途中で止めて、さらにその繰り返し処理から抜けさせるときに使う。
switch文の中で使われるbreakと単語は同じだが、全然別の意味なので注意。
Javaでは、
break ラベル;
として、抜け出す繰り返しを指定できる。つまり、一番内側にある繰り返しでなくても、外側の繰り返しの始まり部分に
ラベル:
をつければ、「break ラベル;」により、その繰り返しから抜け出させることができる。

今回出てきた重要事項

変数に対する加減乗除・剰余

変数に対して加減乗除を施すために、決まった書き方がある。


演習5 : 右上直角の三角形の表示

下図のような右上が直角の三角形状にアスタリスク文字(*)を並べて画面表示するプログラム (クラス名 Ex5、ファイル Ex5.java) を書きなさい。

外側が行単位で、内側が文字単位による、二重の繰り返し構文を使って表示させること。

※ Java 11以降では、内側の繰り返しを使う代わりに、String の repeat メソッドを使ってスペースまたはアスタリスクを指定個数出力させることができる。しかしながら、この講義内の決まり事として、演習およびテストでの類題において、repeat メソッドを使わずに、二重ループの問題として記述する必要がある。

三角形の高さ (アスタリスクの数) を変数 h で表す。メッセージを出して、キーボードから h の値を入力するものとする。
h は 2 から 15 の範囲の整数とし、それ以外はエラーメッセージを表示して終了させること。下図は h に 5 を入力した例。アスタリスク(*)とスペースの文字幅が等しい等幅フォントを使っている前提で書いてよい。

サイズ5の右上直角の三角形

正しい動作を確認できたら、

をテキストファイル (拡張子 txt) にまとめる。

考え方

多く見られる間違い

解答例 (演習課題名、クラス名が異なる可能性あり。以下も同様)


演習6 : 4タイプの直角三角形の表示

ひとつ前のファイル Ex5.java を Ex6.java としてコピーし、クラス名を Ex6 に変更し、以下のように追加修正しなさい。

入力された三角形の高さが2〜15のとき

三角形のタイプ(1〜4)を指定してください
1. 左上直角
2. 右上直角
3. 左下直角
4. 右下直角

のようなメッセージを出して三角形のタイプ(1〜4)を入力し、指定されたタイプで表示するようにしなさい。

図形は、外側が行単位で、内側が文字単位による、二重の繰り返し構文を使って表示させること。

タイプが 1 〜 4 の範囲にない場合は適切なエラーメッセージを表示して終了させること。

正しい動作を確認できたら、

をテキストファイル (拡張子 txt) にまとめる。

考え方

多く見られる間違い

解答例


演習7 : 自然対数の底 e の近似計算

以下のプログラム Ex7 (ファイル Ex7.java) を作りなさい。

自然対数の底 e を求める一方法

1 + 1/1! + 1/2! + 1/3! + ...

の途中までの和を求めることで、e の近似値を計算させる。 まず、整数 n の値を入力し、以下の式で e の近似値を求める。

1 + 1/1! + 1/2! + 1/3! + ... + 1/n!

ただし、この演習プログラムでは、上式の左から右に順に加算していくものとする。

n の入力が整数でないか 0 以下の値ならエラーを表示して終了させる。
e の近似値はdoubleで計算し、近似値自身 および Math.E との差 を表示する。

コンパイル・実行し、下記入力をしてみなさい。

  1. n の入力値を 自分の学籍番号が 25CWXYZ として、Z (Z≠0 のとき)、または WX (Z=0のとき) としたとき。
  2. n を1ずつ大きくしていっても、n がある値以上になると結果が変化しなくなる。
    結果が変化しなくなる最初の n の値。

以下をテキストファイル (拡張子 txt) にまとめる。

多く見られる間違い

解答例


配列


Javaにおける配列

Javaでは、配列は「配列オブジェクト」として扱われる。
使い方は C/C++ と似ている。インデックスは 0 から数える。

※ ただし、例えば a を一次元配列としたとき、C/C++ で成立する
a[3] ≡ *(a + 3) ≡ *(3 + a) ≡ 3[a]
のような関係は成り立たない。a[3] の形式のみ許される。

多次元配列は、配列の要素を配列とすることによって作る。


データ型[ ] 配列名;   または
データ型 配列名[ ];

データ型元となる要素の型
配列名その配列を表す変数名
 配列名[インデックス] の形で個々の要素を指し示す。

配列型の変数を作成する。変数自体の値は null (インスタンス変数またはクラス変数のとき) または不定 (ローカル変数のとき)。

※ null はその変数に有効なオブジェクトが結び付けられていないことを示す特殊な値。
  null は英語発音では nʌ́l (ナル) だが、日本では ヌル と言う人が多い。

データ型[ ] 配列名;  も   データ型 配列名[ ];  も同じ意味。以下でも同様。
Java の配列の意味をよく表しているのは前者なので、ここでは前者のみ用いる。

----------------------------------------------------------------------

データ型[ ] 配列名 = new データ型[サイズ];

データ型元となる要素の型
配列名その配列を表す変数名
 配列名[インデックス] の形で個々の要素を指し示す。
サイズその配列の要素数

大きさ「サイズ」の配列を宣言する。配列名[0] から配列名[サイズ - 1] までのサイズ個の要素が確保される。
要素の初期値は 0 (整数型・浮動小数点型)、'\u0' (char型)、false (boolean型)、null (String型などのオブジェクト型)

----------------------------------------------------------------------

データ型[ ] 配列名 = { 初期化データの並び };

データ型元となる要素の型
配列名その配列を表す変数名
 配列名[インデックス] の形で個々の要素を指し示す。
初期化データの並びその配列を初期化するデータをコンマで区切って並べる。

「初期化データの並び」で指定される配列を宣言する。配列の大きさは初期化データの大きさになる。


配列名.length

その配列の大きさを表す。


例

int[ ] a = new int[10];

int型の要素10個を持つ配列 a を作る。要素は a[0] から a[9] までで、すべて 0 になっている。
a.length は 10 になる。


double[ ] x = { 11.4, 83.5, 16.3, 20.7 };

double型の要素4個を持つ配列 x を作る。要素は x[0] (値 11.4) から x[3] (値 20.7) まで。
x.length は 4 になる。


String[ ] sel = new String[3];

String型の要素3個を持つ配列 sel を作る。
要素は sel[0], sel[1], sel[2] で、すべて null になる。空文字列 "" で初期化されるわけではないので注意。


String[ ] msg = { "No", "Yes" };

String型の要素2個を持つ配列 msg を作る。
要素は msg[0] が値 "No"、 msg[1] が値 "Yes" に初期化される。


double[ ][ ] mat = new double[5][3];

double型のサイズ5×3の2次元配列 mat を作る。
実際には、「サイズ3のdouble型配列」を5個持つ配列、となる。
要素はすべて 0 に初期化される。


演習8 :   表の計算と表示

  1. 下図のように九九の表を表示させるプログラム Ex8_1 (クラス名 Ex8_1、ファイル Ex8_1.java) を作りなさい。
    整数の2次元配列(9×9サイズ)を定義し、for文の二重ループによって、

    配列[i][j]     1-1 <= i <= 9-1,   1-1 <= j <= 9-1

    の各要素が対応する九九の値を持つように設定する。
    最後に、計算した九九の表を、for文の二重ループによって表示する。
    縦方向に文字をそろえ、きれいな表とすること。簡単には、表の中の値を System.out.printf で桁数を指定して表示させればよい。

    九九の表出力

  2. ファイル Ex8_1.java を Ex8_2.java という名前にコピーしクラス名も変更する。
    Ex8_2 のプログラム (クラス名 Ex8_2、ファイル Ex8_2.java) を、
    整数 n を 自分の学籍番号が 25CWXYZ として、n = Z (Z≠0,1 のとき)、または n = 9-Z (Z=0,1 のとき) として

    2次元配列の各要素が、「九九の値」を n で割った余り

    を持つように変更し、出力を示しなさい。
    縦方向に文字をそろえ、きれいな表とすること。

    ※ 参考のため、学籍番号 25C4321 (Z=1) のとき、すなわち n = 9-Z = 8 のときの出力を下に示す。(実際の出力は学籍番号によって異なる)

    九九の表2出力

正しい動作を確認できたら、

をテキストファイル (拡張子 txt) にまとめる。

多く見られる間違い

解答例


演習9 :   文字コード表

	char[] codeTable = new char[256];

のように、256個の要素を持つchar配列を定義し、

	for (int c = 32; c <= 126; c++) {
		codeTable[c] = (char)c;
	}

のように、32〜126 の範囲にコードに対応する文字を入れておく。

この codeTable 配列の値を使って、以下のように、
まず、ある文字コード(10進で 32〜126 の範囲)を入力して、それに対応する文字を表示し、
その下に、文字コード(32〜126)の文字の対応表を表示するプログラム Ex9 (ファイル Ex9.java) を作成しなさい。

文字コード表出力

正しい動作を確認できたら、

をテキストファイル (拡張子 txt) にまとめる。

多く見られる間違い

解答例


演習10 :   16進の文字コード表

上の演習プログラムを、コードの入力を10進でなく16進で行うプログラム Ex10 (ファイル Ex10.java) に変更しなさい。

出力例:
16進文字コード表出力

正しい動作を確認できたら、

をテキストファイル (拡張子 txt) にまとめる。

解答例


課題2 : 三角関数 sine の表示

まずアスタリスクの個数 (3個以上80個以下とする) を入力し、 2次元配列を使って下のようにアスタリスクで三角関数 sine のグラフを出力するプログラムを作りなさい。
角度は 0°から 10°きざみで増加させ、値は -1 〜 1 の範囲を20等分した21レベルで表す。

表示にはスペースとアスタリスクが同じ幅の等幅フォントを使用するものと仮定してよい。

アスタリスク数が整数で入力されなかった場合は、「入力が整数ではありません」と表示して終了させること。

入力されたアスタリスク数が 3 個以上 80 個以下の範囲にない場合は、「アスタリスク数が規定の範囲にありません」と表示して終了させること。

アスタリスク数として、

① 自分の学籍番号が 25CWXYZ として、YZ + 30 個 (YZ < 20 のとき)、または YZ 個 (YZ >= 20 かつ YZ <= 50 のとき)、または YZ - 30 個 (YZ > 50 のとき)
② 2
③ 3
④ 80
⑤ 81

の5通りの入力をして、結果を順に示すこと。


プログラムの大まかな処理を示す。
グラフ領域のための2次元配列を用意し、全てスペースで初期化した後、sine値に相当する部分だけアスタリスクに変える。
値の最上部 (=1) に相当するところ (インデックス最大値) から最下部 (=-1) に相当するところ (インデックス 0) まで一行ずつ表示させる。


出力例1 : アスタリスク数として 100 を入力した場合

sin曲線を 0°から 10°刻みでアスタリスクで表示します
アスタリスク数 (3-80) は?  100
アスタリスク数が規定の範囲にありません

出力例2 : アスタリスク数として 37 を入力した場合

sin曲線を 0°から 10°刻みでアスタリスクで表示します
アスタリスク数 (3-80) は?  37

        ***
      **   **
     *       *

    *         *
   *           *

  *             *
 *               *

*                 *                 *

                   *               *
                    *             *

                     *           *
                      *         *

                       *       *
                        **   **
                          ***

プログラム出力の形式・文字列は、上の出力例1, 出力例2 に示したものに一致させること。

sine関数の値は Math.sin メソッド で求められる。ただし、渡す角度の値はラジアン単位でなければならない。度からラジアンに変換するには π/180 を掛ければいいので、結局、以下のような求め方となる。

sine関数の値 = Math.sin( 度単位の角度 * Math.PI / 180 );

もしくは、下記の様に、Mathクラスの toRadians メソッドを使って度からラジアンに変換してもよい。

sine関数の値 = Math.sin( Math.toRadians(度単位の角度) );

また、この課題では、「sine関数の値 + 1」を 10 倍し、さらに整数化して配列の縦方向のインデックスとする。その際、小数点のついた値 (double型) に最も近い整数を求めるため、Math.round メソッド を使用する。パラメータとして double 値を受け取る Math.round の戻り値は long 型なので int にキャストする。結局、以下のような求め方となる。

配列の縦方向のインデックス = (int) Math.round( 10 * ( sine関数の値 + 1 ) );

今までの演習のソースファイルをコピーした後、ファイル名を Kadai2s.java に変更した上で編集し、クラス名を Kadai2s に変更してから本体分を入力してプログラムを完成させなさい。
その際、javadocコメントも、課題に合うように、クラスの説明部分の

課題番号 : 課題名

を、この課題に合わせて変更する。また、@author 部分の 学籍番号・氏名 も確認しておくこと。

以下をテキストファイル (拡張子 txt) にまとめて授業のWebページから提出しなさい。

多く見られる間違い

考え方


拡張for文による繰り返し (Java 5 以降)

拡張for文 は、ある種のデータの集まり (配列、リストなど java.lang.Iterable インタフェースを実装したオブジェクト) が持つ各要素に対して、繰り返し何らかの処理を行わせるときに使う。for-each文 といわれる場合もある。

for   ( 要素の型   変数名   :   データの集まり )   {

     処理

     「データの集まり」の中にある個々の要素が、順に、「変数名」でアクセスできる。

}

※ Java 10以降は、拡張forの「要素の型」を明示せず、var を使って型推論させることができるようになった。

例

int[ ] ar = { 5, 2, 9, 1 };
int sum = 0;
for (var e : ar) {
	sum += e;
	System.out.print(e + " ");
}
System.out.println("sum=" + sum);

配列 ar の個々の要素が順に変数 e として繰り返し処理の内部で使われる。このコードをmainメソッドの中に入れて実行させると、出力は

5 2 9 1 sum=17

となる。

なお、この例では拡張forで var を使っているが、型を明示する場合、int配列 ar の各要素の型となるので int を指定すればよい。

for (int e : ar) {



演習11 : 単語をつなぎ合わせて文を出力 (拡張forを使う)

以下に説明するプログラム (クラス名 Ex11、ファイル名 Ex11.java) を作成しなさい。

下記の要素を持つ文字列配列を定義し、

"The", "jay,", "pig,", "fox,", "zebra",
"and", "my", "wolves", "quack", "!",
"Quick", "brown", "fox", "jumps",
"over", "the", "lazy", "dog", ".",
"Who", "packed", "five", "dozen", "old",
"quart", "jugs", "in", "my", "box", "?"

mainメソッド中で、拡張for文を使って、配列の各要素を、間に空白を入れて出力させなさい。ただし、要素が

"."
"!"
"?"

に等しいときは、前にも後ろにも空白を入れず、その代わりに後ろに改行 (System.lineSeparator() で取得したもの) を出力させなさい。

String の一致は equals メソッドで判定できる。一致する場合は true、しない場合は false が返る。

なお、出力する各行の先頭には余分な空白を入れてはいけない。

出力: (英語のパングラム (pangram) 3文)

パングラム3文

正しい動作を確認できたら、

をテキストファイル (拡張子 txt) にまとめる。