4 プログラムに知性を(条件分岐)

4.1 学習目標

4.2 条件分岐を使う

今回のテーマは条件に応じて動作が変化するプログラムを書くことです。

ユーザの入力に応じた絵を書かせてみましょう。

4.2.1 条件分岐

次のプログラムを見てみましょう。

図 4.2.1.1 Condition
リスト 4.2.1.1 Condition.java
  1: /*
  2:  * 入力された番号の絵を書くプログラム
  3:  * 2003/05/08  Yoshiaki Matsuzawa
  4:  * 2012/10/16 改訂 Yoshiaki Matsuzawa
  5:  */
  6: public class Condition extends Turtle {
  7: 
  8: 	// 起動処理
  9: 	public static void main(String[] args) {
 10: 		Turtle.startTurtle(new Condition());
 11: 	}
 12: 
 13: 	// タートルを動かす処理
 14: 	public void start() {
 15: 
 16: 		int pictureNumber;// 絵の番号
 17: 
 18: 		{// ユーザから入力を受け取る
 19: 			print("書きたい絵の番号を入力してください。(1.家, 2.星)");
 20: 			pictureNumber = input();
 21: 		}
 22: 
 23: 		if (pictureNumber == 1) {// 入力された番号が1ならば
 24: 			{// c//家を書く
 25: 
 26: 				int length = 50;// 1辺の長さ
 27: 				int rightAngle = 90;// 直角
 28: 
 29: 				{// 屋根を書く
 30: 					rt(30); // 30度右に回る
 31: 					fd(length); // x歩前に進む
 32: 					rt(120);
 33: 					fd(length);
 34: 					rt(120);
 35: 					fd(length);
 36: 				}
 37: 
 38: 				{// 本体を書く
 39: 					lt(rightAngle);
 40: 					fd(length);
 41: 					lt(rightAngle);
 42: 					fd(length);
 43: 					lt(rightAngle);
 44: 					fd(length);
 45: 					lt(rightAngle);
 46: 					fd(length);
 47: 				}
 48: 			}
 49: 
 50: 		} else {// 入力された番号が1以外ならば
 51: 			{// c//星を書く
 52: 
 53: 				int length = 100;// 1辺の長さ
 54: 				int angle = 144;// 星を書くときに曲がる角度
 55: 
 56: 				{// 星を書く
 57: 					rt(18);
 58: 					fd(length);
 59: 					rt(angle);
 60: 					fd(length);
 61: 					rt(angle);
 62: 					fd(length);
 63: 					rt(angle);
 64: 					fd(length);
 65: 					rt(angle);
 66: 					fd(length);
 67: 				}
 68: 			}
 69: 
 70: 		}
 71: 
 72: 	}
 73: 
 74: }

ここ をクリックすると、プログラムをダウンロードできます。

下のボタンを押すと、Conditionプログラムが実行できます。

いままでのプログラムでは、命令が必ず上から順番に全て実行されていました。 これを順次実行といいます。

今回登場する"条件分岐"を使うと、命令の実行される順番を変更、制御することができます。

条件分岐の一般的な形は次のとおりです。

if( [条件式] ) {
	処理A
} else {
	処理B
}
				

条件式が成立(true)のした場合には、処理Aが実行され、処理Bは実行されません。

逆に条件式が不成立(false)の場合には、処理Bが実行され、処理Aは実行されません。

これをフローチャートと呼ばれる図を用いて書くと、次のようになります。

図 4.2.1.2 条件分岐のフローチャート

ちなみに、elseブロックは必要が無ければ省略できます。次のような形になります。

if( [条件式] ) {
	処理A
}
				

このように書くと、条件式が成立した時に処理Aが実行され、不成立の時には処理Aを飛ばします。

4.2.2 条件式の評価

条件式の評価の過程を見ていきましょう。

4.2.2.1 成立(true)する場合

図 4.2.2.1.1 成立(true)する場合

4.2.2.2 不成立(false)する場合

図 4.2.2.2.1 不成立(false)する場合

4.2.2.3 注意すること

注意することは、条件式で、同じかどうか調べるには「==」(イコールを2つ)にしなければならないことです。

これに対して、「=」(イコール1つ)は代入ですので、注意してください。

4.2.3 複数の分岐

4.2.3.1 じゃんけんプログラム

複数に分岐するプログラムを書くこともできます。

次のじゃんけんプログラムを見てみましょう。

図 4.2.3.1.1 Janken
リスト 4.2.3.1.1 Janken.java
  1: /*
  2:  * じゃんけんプログラム
  3:  * 2003/05/08  Yoshiaki Matsuzawa
  4:  * 2012/10/16 改訂 Yoshiaki Matsuzawa
  5:  */
  6: public class Janken extends Turtle {
  7: 
  8: 	// 起動処理
  9: 	public static void main(String[] args) {
 10: 		Turtle.startTurtle(new Janken());
 11: 	}
 12: 
 13: 	// タートルを動かす処理
 14: 	public void start() {
 15: 
 16: 		int handNumber;// じゃんけんの手
 17: 
 18: 		// じゃんけんの手は 1をグー,2をチョキ,3をパーとする
 19: 		handNumber = random(3) + 1;// random(3)は0から2までの値を発生するので1を足す
 20: 
 21: 		if (handNumber == 1) {
 22: 			{// c//グーを書く
 23: 				fd(30);
 24: 
 25: 				lt(30);
 26: 				fd(25);
 27: 				rt(60);
 28: 				fd(25);
 29: 				rt(150);
 30: 				fd(30);
 31: 				lt(180);
 32: 				fd(20);
 33: 
 34: 				fd(20);
 35: 				rt(90);
 36: 				fd(20);
 37: 				rt(90);
 38: 				fd(20);
 39: 				lt(90);
 40: 				fd(5);
 41: 
 42: 				lt(90);
 43: 				fd(20);
 44: 				rt(90);
 45: 				fd(20);
 46: 				rt(90);
 47: 				fd(20);
 48: 				lt(90);
 49: 				fd(5);
 50: 
 51: 				lt(90);
 52: 				fd(20);
 53: 				rt(90);
 54: 				fd(20);
 55: 				rt(90);
 56: 				fd(20);
 57: 				lt(90);
 58: 				fd(5);
 59: 
 60: 				lt(90);
 61: 				fd(20);
 62: 				rt(90);
 63: 				fd(20);
 64: 				rt(90);
 65: 				fd(20);
 66: 
 67: 				fd(65);
 68: 			}
 69: 
 70: 		} else if (handNumber == 2) {
 71: 			{// c//チョキを書く
 72: 
 73: 				fd(30);
 74: 
 75: 				lt(30);
 76: 				fd(25);
 77: 				rt(60);
 78: 				fd(25);
 79: 				rt(150);
 80: 				fd(30);
 81: 				lt(180);
 82: 				fd(30);
 83: 
 84: 				lt(15);
 85: 				fd(80);
 86: 				rt(105);
 87: 				fd(20);
 88: 				rt(75);
 89: 				fd(80);
 90: 				lt(75);
 91: 
 92: 				lt(75);
 93: 				fd(80);
 94: 				rt(75);
 95: 				fd(20);
 96: 				rt(105);
 97: 				fd(80);
 98: 				fd(20);
 99: 				lt(105);
100: 				fd(5);
101: 
102: 				lt(90);
103: 				fd(20);
104: 				rt(90);
105: 				fd(20);
106: 				rt(90);
107: 				fd(20);
108: 				lt(90);
109: 				fd(5);
110: 
111: 				lt(90);
112: 				fd(20);
113: 				rt(90);
114: 				fd(20);
115: 				rt(90);
116: 				fd(20);
117: 
118: 				fd(65);
119: 			}
120: 
121: 		} else if (handNumber == 3) {
122: 			{// c//パーを書く
123: 
124: 				fd(30);
125: 
126: 				lt(30);
127: 				fd(80);
128: 				rt(120);
129: 				fd(20);
130: 				rt(60);
131: 				fd(40);
132: 				lt(150);
133: 				fd(15);
134: 
135: 				fd(80);
136: 				rt(90);
137: 				fd(20);
138: 				rt(90);
139: 				fd(80);
140: 				lt(90);
141: 				fd(5);
142: 
143: 				lt(90);
144: 				fd(80);
145: 				rt(90);
146: 				fd(20);
147: 				rt(90);
148: 				fd(80);
149: 				lt(90);
150: 				fd(5);
151: 
152: 				lt(90);
153: 				fd(80);
154: 				rt(90);
155: 				fd(20);
156: 				rt(90);
157: 				fd(80);
158: 				lt(90);
159: 				fd(5);
160: 
161: 				lt(90);
162: 				fd(80);
163: 				rt(90);
164: 				fd(20);
165: 				rt(90);
166: 				fd(80);
167: 
168: 				fd(75);
169: 			}
170: 
171: 		} else { // 1,2,3以外の場合
172: 
173: 			print("不正な数です。");
174: 
175: 		}
176: 
177: 	}
178: 
179: }

ここ をクリックすると、プログラムをダウンロードできます。

下のボタンを押すと、Jankenプログラムが実行できます。

4.2.3.2 じゃんけんの手のデータの扱いについて

じゃんけんプログラムのような現実問題を扱うときに問題となるのは、 データ(グー、チョキ、パーの手)をどうコンピュータで扱えるようにするかです。 コンピュータでは、そのままこの概念を表すことができないので、 ここでは、1,2,3の数値で表すという方法で実現することを考えましょう。

図 4.2.3.2.1 じゃんけんの手をどのようにプログラムのデータとして扱うか

このように、現実に即したプログラムを作成するためには、 データをコンピュータが扱う形式に変換するという作業が必要になります。 この作業のことをデータ構造の設計(モデル化)といいます。

4.2.3.3 複数の条件分岐

else if 文を使うと、複数にわたる条件分岐を記述することができます。

記述例(書式)を以下に示します。ちなみに、一つのif文に対して、else if文はいくつでも書くことができます。

if( [条件式] ) {
	処理A
} else if( [条件式] ) {
	処理B
} else{
	処理C
}
					

この場合のフローチャートは次のようになります。

図 4.2.3.3.1 複数にわたる条件分岐のフローチャート

4.3 いろいろな条件式

4.3.1 比較演算子

次のプログラムを見てみましょう。

図 4.3.1.1 Rohrer
リスト 4.3.1.1 Rohrer.java
  1: /*
  2:  * 健康管理プログラム
  3:  * (身長と体重からローレル指数を計算し、体型に対するコメントを表示する)
  4:  * 2003/05/08  Yoshiaki Matsuzawa
  5:  * 2012/10/16 改訂 Yoshiaki Matsuzawa
  6:  */
  7: public class Rohrer extends Turtle {
  8: 
  9: 	// 起動処理
 10: 	public static void main(String[] args) {
 11: 		Turtle.startTurtle(new Rohrer());
 12: 	}
 13: 
 14: 	// タートルを動かす処理
 15: 	public void start() {
 16: 
 17: 		int height; // 身長
 18: 		int weight; // 体重
 19: 		int rohrer; // ローレル指数
 20: 
 21: 		{// ユーザの入力を受け取る
 22: 			print("身長を入力してください");
 23: 			height = input();
 24: 			print("体重を入力してください");
 25: 			weight = input();
 26: 		}
 27: 
 28: 		{// ローレル指数を求める
 29: 			rohrer = weight * 10000000 / height / height / height;
 30: 			print("ローレル指数は" + rohrer + "です。");
 31: 		}
 32: 
 33: 		{// 体型に対するコメントを提示する
 34: 			if (rohrer < 100) {
 35: 				print("やせすぎですね。");
 36: 			} else if (rohrer < 115) {
 37: 				print("やせていますね。");
 38: 			} else if (rohrer < 145) {
 39: 				print("普通ですね。");
 40: 			} else if (rohrer < 160) {
 41: 				print("太っていますね。");
 42: 			} else {
 43: 				print("太りすぎですね。");
 44: 			}
 45: 		}
 46: 	}
 47: }

ここ をクリックすると、プログラムをダウンロードできます。

下のボタンを押すと、Rohrerプログラムが実行できます。

今度のプログラムでは、ローレル指数の範囲に対応して、メッセージが変わっていますね。 このように、プログラムでは、変数に入っている値が同じかどうかを調べるだけでなく、 大きさの大小を比較して、条件を判定することもできます。

表 4.3.1.1 Javaで使える数値の比較演算子
演算子 表記例 評価
== A==B AとBが同じ値の時成立(true)
!= A!=B AとBが同じ値でない時成立(true)
> A>B AがBより大きい時成立(true)
< A<B AがBより小さい時成立(true)
>= A>=B AがB以上の時成立(true)
<= A<=B AがB以下の時成立(true)

4.3.2 論理演算子

次のプログラムを見てみましょう。

図 4.3.2.1 Rohrer2
リスト 4.3.2.1 Rohrer2.java
  1: /*
  2:  * 健康管理プログラム
  3:  * (身長と体重からローレル指数を計算し、体型に対するコメントを表示する)
  4:  * 2003/05/08  Yoshiaki Matsuzawa
  5:  * 2012/10/16 改訂 Yoshiaki Matsuzawa
  6:  */
  7: public class Rohrer2 extends Turtle {
  8: 
  9: 	// 起動処理
 10: 	public static void main(String[] args) {
 11: 		Turtle.startTurtle(new Rohrer2());
 12: 	}
 13: 
 14: 	// タートルを動かす処理
 15: 	public void start() {
 16: 
 17: 		int height; // 身長
 18: 		int weight; // 体重
 19: 		int rohrer; // ローレル指数
 20: 
 21: 		{// ユーザの入力を受け取る
 22: 			print("身長を入力してください");
 23: 			height = input();
 24: 			print("体重を入力してください");
 25: 			weight = input();
 26: 		}
 27: 
 28: 		{// ローレル指数を求める
 29: 			rohrer = weight * 10000000 / height / height / height;
 30: 			print("ローレル指数は" + rohrer + "です。");
 31: 		}
 32: 
 33: 		{// 体型に対するコメントを提示する
 34: 			if (rohrer < 100) {
 35: 				print("やせすぎですね。");
 36: 			}
 37: 			if (rohrer >= 100 && rohrer < 115) {
 38: 				print("やせていますね。");
 39: 			}
 40: 			if (rohrer >= 115 && rohrer < 145) {
 41: 				print("普通ですね。");
 42: 			}
 43: 			if (rohrer >= 145 && rohrer < 160) {
 44: 				print("太っていますね。");
 45: 			}
 46: 			if (rohrer >= 160) {
 47: 				print("太りすぎですね。");
 48: 			}
 49: 		}
 50: 	}
 51: }

ここ をクリックすると、プログラムをダウンロードできます。

下のボタンを押すと、Rohrer2プログラムが実行できます。

今度のプログラムも、前例とやっていることは同じなのですが、条件文がちょっと異なっていますね。

論理演算子を使うと、2つの条件式を使って、それらの条件が両方とも(And)もしくは、 どちらか(Or)が成立した時のように、組み合わされた条件式全体の条件を判定することができます。

表 4.3.2.1 Javaで使える論理演算子
演算子 表記例 意味
&& A&&B AとB両方ともtrueの時true
|| A||B AもしくはBがtrueの時true

4.3.2.1 論理演算子の評価の過程

論理演算子の評価の過程を見ていきましょう。

And演算子が成立(true)する場合

図 .1 And演算子が成立(true)する場合

And演算子が不成立(false)する場合

図 .1 And演算子が不成立(false)する場合

4.4 変数のスコープ(有効範囲)

変数には有効範囲(スコープといいます)があります.Javaでは基本的に,宣言した変数のブロック内(「{}」で囲まれた範囲)がスコープになります.

例えば、次のような例の場合の各変数のスコープは下表のようになります。

void start(){				
	
	int z;
	
	if( [条件式] ) {
	
		int x;
		処理A
		
	} else {
	
		int y;
		処理B
		
	}
}
				
表 4.4.1 変数のスコープ
変数名 処理A 処理B
x 有効 無効
y 無効 有効
z 有効 有効

スコープ外で変数を呼び出そうとすると、コンパイルエラーが出ます。

スコープ外なら同じ変数名を使うことができます。 その場合、それぞれの変数が違う値を持つことになります。

4.5 練習問題

4.5.1 絵の描き分けプログラムを作ろう

前回作ったプログラムを改造して、条件式を使って、 ユーザの入力に応じて、タートルの書く絵を変えるプログラムを書いてください。 余裕がある人は、条件文を駆使して実用的なプログラムに挑戦してみてください。

ファイル名は「FigureShop.java」とすること.

4.5.2 おみくじプログラムを作ろう

乱数と条件分岐を使って、「大吉」「中吉」「小吉」「凶」を表示するプログラムを作りましょう。 大吉のときだけ、タートルの絵(星など)を描くようにしましょう。

ファイル名は「Omikuji.java」とすること.

4.5.3 評点グレード変換プログラムを作ろう

入力と条件分岐を使って、「秀」「優」「良」「可」「不可」を表示するプログラムを作りましょう。 ユーザが評点を入力すると、それに応じたグレードが表示されるようにプログラムを書いてください。 評点区分とグレードの定義は静大の評価制度を利用すること。

ファイル名は「Grade.java」とすること.