静岡理工科大学 総合情報学部 (by 菅沼) 菅沼ホーム 目次

2.2 繰り返し

  1. 2.2.1 繰り返し文
      (プログラム例2.6) 平均値の計算
      (プログラム例2.7) for 文のネスト
      (プログラム例2.8) 入力の繰り返し( do-while )
      (プログラム例2.9) 最大値(初期設定)
    1. (演習問題)
  2. 2.2.2 繰り返しの中断
    1. 2.2.2.1 break 文
        (プログラム例2.10) 繰り返しの中断( break )
    2. 2.2.2.2 continue 文
        (プログラム例2.11) 繰り返しの中断( continue )

2.2.1 繰り返し文

  プログラムによっては,同じ手順を何回も繰り返して行いたいような場合がよく起こります.for 文は,その様なときに使用します.例えば,5 つのデータを読み込みその和を計算する場合,前節までの方法を使用すれば次のようになります.
import java.io.*;
public class Test1 {
	public static void main(String args[])
	{
		try {
			BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
			double data, sum = 0.0;
			data = Double.parseDouble(in.readLine());
			sum += data;
			data = Double.parseDouble(in.readLine());
			sum += data;
			data = Double.parseDouble(in.readLine());
			sum += data;
			data = Double.parseDouble(in.readLine());
			sum += data;
			data = Double.parseDouble(in.readLine());
			sum += data;
			System.out.println("和=" + sum);
		}
		catch (IOException ignored) {}
	}
}
		
  しかし,5 つ程度のデータであれば,上の方法でも可能ですが,データの数が多くなると非常に困難になります.そこで,このプログラムは,for 文を使用することによって,次のようにより簡単に書くことができます.
import java.io.*;
public class Test2 {
	public static void main(String args[])
	{
		try {
			BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
			double data, sum = 0.0;
			int i1;
			for (i1 = 0; i1 < 5; i1++) {
				data = Double.parseDouble(in.readLine());
				sum += data;
			}
			System.out.println("和=" + sum);
		}
		catch (IOException ignored) {}
	}
}
		
  for 文の一般的形式は以下の通りです.
for (式1; 式2; 式3) {
	文(複数の文も可)
}
 ・・・・・
		
  for 文に入ると,まず,式 1 が実行されます.式 1 は,通常,for 文の繰り返し回数を制御するため等の初期設定を行う式であり,for 文の最初に 1 回だけ実行されます.次に,式 2 (論理式)の値が評価され,もし真( true )であれば 文 が実行されます.そして,式 3 が実行されます.再び,式 2 が評価され,その値が真である限り,文 と 式 3 の実行が繰り返されます.式 2 の値が偽になると,文 と 式 3 は実行されず,「・・・」以下の文が実行されることになります( for 文の外に出る).

  for 文において,式 1 と 式 3 を省略することは可能(「;」は省略できない)ですが,通常,式 2 を省略することはできません(省略すると,無限ループになってしまう).

  for 文と同様な機能を持つ文として,while 文do-while 文があります.while 文,及び,do-while 文の一般形式は以下の通りです.
<while文>
	while (式) {
		文(複数の文も可)
	}
	 ・・・・・

<do-while文>
	do {
		文(複数の文も可)
	} while (式) ;
	 ・・・・・
		
  while 文では,式の値が真である限り,文の実行が繰り返されることになります.while 文と do-while 文の違いは,式の評価が,文を実行する最初に行われるか,または,後で行われるかの違いです.do-while 文では,式の評価が後で行われるため,do-while 文の開始時に式が偽であっても,文が少なくとも 1 回は実行されることになります.

  先に述べた for 文は,while 文を使用して,次のように書くこともできます.どちらの表現方法を使用するかは趣味の問題ですが,問題に応じて,理解しやすいプログラムになると思われる方を使用して下さい.
式1;
while (式2) {
	文(複数の文も可)
	式3;
}
		
  このように,for 文,while 文,及び,do-while 文は基本的に等価ですので,以下の説明では for 文を使用して説明を行います( while 文や do-while 文に対しても同様の議論が成立します).

  if 文と同様,while 文や do-while 文の中が 1 文だけの場合は,{ } を省略可能です.また,次の例のように,for 文の中に別の for 文を書くこともできます( for 文のネスト).
for (式1; 式2; 式3) {
	・・・・・
	for (式4; 式5; 式6) {
		・・・・・
	}
	・・・・・
}
		
  また,if 文と同じように,プログラムを読み易くするため,for 文内の文は,次の例のように,何列か段を下げて(字下げをして)書くようにして下さい.
for (i1 = 0; i1 < 10; i1 = i1+1) {
	a = b + c;
	for (i2 = 0; i2 < 5; i2 = i2+1) {
		bcd = a / y;
		aa  = b;
		・・・・・・・・
	}
	sum = c + d;
}
		

(プログラム例2.6) 平均値の計算 ( A 〜 J ,及び,K 〜 U の部分を可能な限り一つの変数,定数,演算子等で,埋めてください.その際,文字を削除してから,正しい答えを半角文字で,かつ,余分なスペースを入れないで入力してください.)

  以下に,n 人の英語と数学の点数から,それらの平均点を計算するプログラムを,for 文を使用して書いた例を示します.

  参考のため,上のプログラムを while 文を使用して書き直したものを以下に示します.24 行目を修正し,** と記述された行を追加しています.どちらのプログラムも正しく動作しますが,このように繰り返し回数が明確になっているような場合は,for 文を使用した方が理解しやすいのではないかと思います(好みにもよりますが).

  しかし,次に示す例のように,人数を前もって入力せず,英語または数学の点数として負の値を入力した時点でデータ入力を終了したいような場合は,while 文の方がすっきり記述できるかもしれません.
import java.io.*;
import java.util.*;
public class Test3 {
	public static void main(String args[])
	{
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		double mean1, mean2, sum1, sum2;
		int n, i1, x, y;
		String line;
		StringTokenizer str;
					// 初期設定
		sum1 = 0.0;
		sum2 = 0.0;
		n    = 0;
		try {
					// データの読み込み
			System.out.print("英語と数学の点は? ");
			line = in.readLine();
			str  = new StringTokenizer(line, " ");
			x    = Integer.parseInt(str.nextToken());
			y    = Integer.parseInt(str.nextToken());
			while (x >= 0 && y >= 0) {
				n++;
				sum1 += x;
				sum2 += y;
				System.out.print("英語と数学の点は? ");
				line = in.readLine();
				str  = new StringTokenizer(line, " ");
				x    = Integer.parseInt(str.nextToken());
				y    = Integer.parseInt(str.nextToken());
			}
		}
		catch (IOException ignored) {}
					// 結果の計算と出力
		if (n <= 0)
			System.out.println("データがない!");
		else {
			mean1 = sum1 / n;
			mean2 = sum2 / n;
			System.out.println("   英語=" + mean1 + " 数学=" + mean2);
		}
	}
}
		
  上と同じプログラムを do while 文を使用して記述すると以下に示すようになります.一見,こちらの方がよいプログラムのように見えますが,「 x >= 0 && y >= 0 」の判定を余分に行っていることになり,計算時間の点からあまり好ましくありません.
import java.io.*;
import java.util.*;
public class Test4 {
	public static void main(String args[])
	{
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		double mean1, mean2, sum1, sum2;
		int n, i1, x, y;
		String line;
		StringTokenizer str;
					// 初期設定
		sum1 = 0.0;
		sum2 = 0.0;
		n    = 0;
		try {
					// データの読み込み
			do {
				System.out.print("英語と数学の点は? ");
				line = in.readLine();
				str  = new StringTokenizer(line, " ");
				x    = Integer.parseInt(str.nextToken());
				y    = Integer.parseInt(str.nextToken());
				if (x >= 0 && y >= 0) {
					n++;
					sum1 += x;
					sum2 += y;
				}
			} while (x >= 0 && y >= 0);
		}
		catch (IOException ignored) {}
					// 結果の計算と出力
		if (n <= 0)
			System.out.println("データがない!");
		else {
			mean1 = sum1 / n;
			mean2 = sum2 / n;
			System.out.println("   英語=" + mean1 + " 数学=" + mean2);
		}
	}
}
		

(プログラム例2.7) for 文のネスト ( A 〜 F の部分を可能な限り一つの変数,定数,演算子等で,埋めてください.その際,文字を削除してから,正しい答えを半角文字で,かつ,余分なスペースを入れないで入力してください.)

  次に,for 文のネストの例を示します.今,ある学年に,n クラスあったとします.そして,各クラスには m 人(クラス毎に異なる)の生徒がおり,全員に対しある試験を実施したとします.このとき,平均値が最も高いクラス番号( 1 クラスだけであるとします)とその平均値を出力するプログラムは,例えば,以下のようになります.

  この例により,for 文のネスト,変数の初期設定等を理解して下さい.

(プログラム例2.8) 入力の繰り返し( do-while ) ( A 〜 D の部分を可能な限り一つの変数,定数,演算子等で,埋めてください.その際,文字を削除してから,正しい答えを半角文字で,かつ,余分なスペースを入れないで入力してください.)

  次のプログラムでは,要求にあったデータ(正のデータ)が入力されるまで,再入力を促しています.また,要求通りのデータの場合は,和を求め出力しています.この場合も繰り返し回数が未定ですので,do-while 文を使用しています.

(プログラム例2.9) 最大値(初期設定) ( A 〜 D の部分を可能な限り一つの変数,定数,演算子等で,埋めてください.その際,文字を削除してから,正しい答えを半角文字で,かつ,余分なスペースを入れないで入力してください.)

  最大値を求める基本的なアルゴリズムは以下の通りです.まず,最大値を保存する変数,例えば max を適当な値で初期設定しておきます.次に,最大値を求めるデータ群の中の各データと max に代入されている値とを比較し,もし,比較したデータの方が max に代入されている値より大きければ,そのデータを max に代入します.これをすべてのデータに対して繰り返せば最大値が求まることになります.つまり,以下のようにプログラムすればよいわけです.
/****************************/
/* 最大値の計算             */
/*      coded by Y.Suganuma */
/****************************/
import java.io.*;
public class Test1 {
	public static void main(String args[])
	{
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		int n = 5, i1, max = 0, x;
		try {
			for (i1 = 0; i1 < n; i1++) {
				System.out.print("データを入力してください ");
				x = Integer.parseInt(in.readLine());
				if (x > max)
					max = x;
			}
			System.out.println("   最大値=" + max);
		}
		catch (IOException ignored) {}
	}
}
		
  上のプログラムに問題は全くなさそうに見えます.しかし,負のデータだけを入力した場合について考えてみてください.最大値は 0 であるという答えが得られるはずです.明らかに,誤っています.なぜなら,変数 max に初期設定すべき値は,求めるべき最大値より必ず小さくなければならないからです.しかし,求めるべき最大値は不明です.どのようにしたら良いでしょうか.一つの方法は,以下のプログラムのように,最初のデータを max に代入しておく方法です.
import java.io.*;
public class Test2 {
	public static void main(String args[])
	{
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		int n = 5, i1, max, x;
		try {
			System.out.print("データを入力してください ");
			max = Integer.parseInt(in.readLine());   // 最初のデータでmaxを初期化
			for (i1 = 1; i1 < n; i1++) {   // i1 を1から始める
				System.out.print("データを入力してください ");
				x = Integer.parseInt(in.readLine());
				if (x > max)
					max = x;
			}
			System.out.println("   最大値=" + max);
		}
		catch (IOException ignored) {}
	}
}
		
  上のプログラムは,どのようなデータを与えても,正しく最大値を出力してくれるはずです.それでは,問題を少し変えて,「与えられたデータの内,負のデータの最大値を求めよ」というようにしたらどうでしょうか.max とデータを比較している部分を,
if (x < 0 && x > max)
		
のように変えてやればうまくいくよう思われるかもしれません.たしかに,最初のデータが負であるときは正しく動きます.しかし,そうでないときは誤った最大値を出力してしまいます.これを回避する一つの方法は,以下のプログラムのように,変数 max が初期化されたか否かを示す指標(変数 sw )をもうけてやることです.このとき,論理的には,6 行目における max に対する初期化は必要がありませんが,何らかの値で初期化を行っておかないとコンパイルエラーになってしまいます.

-------------------------演習問題開始-------------------------

  早速,演習問題に入ります.今までよりかなり量が多いと思いますが,必ずすべての問題をやってください.まず,プログラムを読み,実行順序を理解する問題です.

  以下の問題は,単純な繰り返しループによって書けるはずです.

  以下の問題では,多重のループが必要のはずです.

-------------------------演習問題終了-------------------------

2.2.2 繰り返しの中断

  通常,繰り返し文は,条件が成立するまで続けられますが,場合によっては,繰り返しの途中でループの外へ出たい場合があります.この節では,そのような場合に使用する文について解説します.

2.2.2.1 break 文

  break 文は,break を囲んでいる最も内側の for 文,while 文,または,do-while 文を終了させ,それらの次の文に制御を移します.また,switch 文においても,しばしば使用されます.

(プログラム例2.10) 繰り返しの中断( break ) ( A 〜 D の部分を可能な限り一つの変数,定数,演算子等で,埋めてください.その際,文字を削除してから,正しい答えを半角文字で,かつ,余分なスペースを入れないで入力してください.)

  次のプログラムは,n 個のデータの和を求めるプログラムですが,負のデータが入力されると,その時点で for ループの外に出ます.
/**********************************/
/* データの和(負のデータで終了) */
/*      coded by Y.Suganuma       */
/**********************************/
import java.io.*;
public class Test1 {
	public static void main(String args[])
	{
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		int i1, n, x, sum = 0;
		try {
					// データ数の入力
			System.out.print("データ数は? ");
			n = Integer.parseInt(in.readLine());
					// 和の計算
			for (i1 = 0; i1 < n; i1++) {
				System.out.print("   データを入力して下さい ");
				x = Integer.parseInt(in.readLine());
				if (x < 0)
					break;
				else
					sum += x;
			}
					// 出力
			System.out.println("和=" + sum);
		}
		catch (IOException ignored) {}
	}
}
		
  上のプログラムは,break 文を使用せず,以下に示すような方法で書くことも可能です.

2.2.2.2 continue 文

  continue 文は,for 文,while 文,または,do-while 文本体の残りを実行せずに,次の繰り返しを実行します.break 文と似ていますが,continue 文では,break のように現在の繰り返し自身を終了させるわけではありません.

(プログラム例2.11) 繰り返しの中断( continue )

  次のプログラムは,n 個のデータの和を求めるプログラムですが,負のデータが入力された場合はそのデータを除外します.
/**********************************/
/* データの和(負のデータを除外) */
/*      coded by Y.Suganuma       */
/**********************************/
import java.io.*;
public class Test {
	public static void main(String args[])
	{
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		int i1, n, x, sum = 0;
		try {
					// データ数の入力
			System.out.print("データ数は? ");
			n = Integer.parseInt(in.readLine());
					// 和の計算
			for (i1 = 0; i1 < n; i1++) {
				System.out.print("   データを入力して下さい ");
				x = Integer.parseInt(in.readLine());
				if (x < 0)
					continue;
				else
					sum += x;
			}
					// 出力
			System.out.println("和=" + sum);
		}
		catch (IOException ignored) {}
	}
}
		

静岡理工科大学 総合情報学部 (by 菅沼) 菅沼ホーム 目次 2.1節 3章