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

4.1 学習目標

4.2 条件分岐を使う

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

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

4.2.1 条件分岐

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

リスト 4.2.1.1 Condition.java
  1: /*
  2:  * 入力された番号の絵を書くプログラム
  3:  * 2003/05/08
  4:  * 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: 		print("書きたい絵の番号を入力してください。(1.家, 2.星)");
 19: 		pictureNumber = input();
 20: 
 21: 		if(pictureNumber == 1){//入力された番号が1ならば家を書く
 22: 						
 23: 			int length;//1辺の長さ
 24: 			int rightAngle;//直角
 25: 		
 26: 			length = 50;//1辺の長さを50に設定する
 27: 			rightAngle = 90;//直角を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: 			lt(rightAngle);
 39: 			fd(length);
 40: 			lt(rightAngle);
 41: 			fd(length);
 42: 			lt(rightAngle);
 43: 			fd(length);
 44: 			lt(rightAngle);
 45: 			fd(length);
 46: 			
 47: 		} else {//入力された番号が1以外ならば星を書く
 48: 
 49: 			int length;//1辺の長さ
 50: 			int angle;//星を書くときに曲がる角度
 51: 			
 52: 			length = 100;//1辺の長さを100に設定する
 53: 			angle = 144;//曲がる角度を144度に設定する
 54: 			
 55: 			//星を書く
 56: 			rt(18);
 57: 			fd(length);
 58: 			rt(angle);
 59: 			fd(length);
 60: 			rt(angle);
 61: 			fd(length);
 62: 			rt(angle);
 63: 			fd(length);
 64: 			rt(angle);
 65: 			fd(length);
 66: 			
 67: 		}
 68: 		
 69: 	}
 70: 
 71: }

下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。

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

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

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

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

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

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

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

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

ちなみに、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.java
  1: /*
  2:  * じゃんけんプログラム
  3:  * 2003/05/08
  4:  * 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: 			
 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: 		} else if(handNumber == 2){//チョキの場合
 70: 			
 71: 			fd(30);
 72: 			
 73: 			lt(30);
 74: 			fd(25);
 75: 			rt(60);
 76: 			fd(25);
 77: 			rt(150);
 78: 			fd(30);
 79: 			lt(180);
 80: 			fd(30);
 81: 			
 82: 			lt(15);
 83: 			fd(80);
 84: 			rt(105);
 85: 			fd(20);
 86: 			rt(75);
 87: 			fd(80);
 88: 			lt(75);
 89: 			
 90: 			lt(75);
 91: 			fd(80);
 92: 			rt(75);
 93: 			fd(20);
 94: 			rt(105);
 95: 			fd(80);
 96: 			fd(20);
 97: 			lt(105);
 98: 			fd(5);
 99: 
100: 			lt(90);
101: 			fd(20);
102: 			rt(90);
103: 			fd(20);
104: 			rt(90);
105: 			fd(20);
106: 			lt(90);
107: 			fd(5);
108: 			
109: 			lt(90);			
110: 			fd(20);
111: 			rt(90);
112: 			fd(20);
113: 			rt(90);
114: 			fd(20);
115: 
116: 			fd(65);
117: 			
118: 		} else if(handNumber == 3){//パーの場合
119: 		
120: 			fd(30);
121: 			
122: 			lt(30);
123: 			fd(80);
124: 			rt(120);
125: 			fd(20);
126: 			rt(60);
127: 			fd(40);
128: 			lt(150);
129: 			fd(15);
130: 			
131: 			fd(80);
132: 			rt(90);
133: 			fd(20);
134: 			rt(90);
135: 			fd(80);
136: 			lt(90);
137: 			fd(5);
138: 			
139: 			lt(90);
140: 			fd(80);
141: 			rt(90);
142: 			fd(20);
143: 			rt(90);
144: 			fd(80);
145: 			lt(90);
146: 			fd(5);
147: 
148: 			lt(90);
149: 			fd(80);
150: 			rt(90);
151: 			fd(20);
152: 			rt(90);
153: 			fd(80);
154: 			lt(90);
155: 			fd(5);
156: 			
157: 			lt(90);
158: 			fd(80);
159: 			rt(90);
160: 			fd(20);
161: 			rt(90);
162: 			fd(80);
163: 
164: 			fd(75);
165: 					
166: 		} else { //1,2,3以外の場合
167: 		
168: 			print("不正な数です。");
169: 			
170: 		}
171: 		
172: 	}
173: 
174: }

下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。

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.java
  1: /*
  2:  * 健康管理プログラム
  3:  * (身長と体重からローレル指数を計算し、体型に対するコメントを表示する)
  4:  * 2003/05/08
  5:  * 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: 		print("身長を入力してください");
 22: 		height = input();
 23: 		print("体重を入力してください");
 24: 		weight = input();
 25: 
 26: 		//ローレル指数を求める
 27: 		rohrer = weight * 10000000 / height / height / height;
 28: 
 29: 		//ローレル指数を表示する
 30: 		print("ローレル指数は" + rohrer + "です。");
 31: 
 32: 		//体型に対するコメントを提示する
 33: 		if (rohrer < 100) {
 34: 			print("やせすぎですね。");
 35: 		}
 36: 		else if (rohrer < 115) {
 37: 			print("やせていますね。");
 38: 		}
 39: 		else if (rohrer < 145) {
 40: 			print("普通ですね。");
 41: 		}
 42: 		else if (rohrer < 160) {
 43: 			print("太っていますね。");
 44: 		}
 45: 		else {
 46: 			print("太りすぎですね。");
 47: 		}
 48: 	}
 49: }

下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。

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

表 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.java
  1: /*
  2:  * 健康管理プログラム
  3:  * (身長と体重からローレル指数を計算し、体型に対するコメントを表示する)
  4:  * 2003/05/08
  5:  * 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: 		print("身長を入力してください");
 22: 		height = input();
 23: 		print("体重を入力してください");
 24: 		weight = input();
 25: 
 26: 		//ローレル指数を求める
 27: 		rohrer = weight * 10000000 / height / height / height;
 28: 
 29: 		//ローレル指数を表示する
 30: 		print("ローレル指数は" + rohrer + "です。");
 31: 
 32: 		//体型に対するコメントを提示する
 33: 		if (rohrer < 100) {
 34: 			print("やせすぎですね。");
 35: 		}
 36: 		if (rohrer >= 100 && rohrer < 115) {
 37: 			print("やせていますね。");
 38: 		}
 39: 		if (rohrer >= 115 && rohrer < 145) {
 40: 			print("普通ですね。");
 41: 		}
 42: 		if (rohrer >= 145 && rohrer < 160) {
 43: 			print("太っていますね。");
 44: 		}
 45: 		if (rohrer >= 160) {
 46: 			print("太りすぎですね。");
 47: 		}
 48: 	}
 49: }

下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。

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

論理演算子を使うと、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 変数の有効範囲

変数はブロック(「{}」で囲まれた範囲)内でのみ有効なので注意しましょう。

例えば、次のような例の場合の変数の有効範囲は下表のようになります。

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 問題1:絵の描き分けプログラムを作ろう

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

4.5.2 問題2:おみくじプログラムを作ろう

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