12 プログラムの構造化(1)(関数・引数)

12.1 学習目標

12.2 関数

12.2.1 関数とは

関数とは、処理のまとまりのことです。 処理をまとめ、関数化することで、

というメリットがあります。

12.2.2 四角形を描くプログラム

以下のプログラムは、関数を使って四角形を描くプログラムです。

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

リスト 12.2.2.1 四角形_関数.dama
  1: ※プログラム名:四角形を描くプログラム
  2: ※       (メソッドの作り方の練習)
  3: ※作成者:秋山 優
  4: ※作成日:2009.12.05
  5: 
  6: ※授業に必要なライブラリを取り込む。
  7: TurtleLibraryを参照する。
  8: 
  9: ※環境を初期化する。
 10: ウィンドウを初期化する。
 11: 亀を新規作成して、亀太郎と名付ける。
 12: ウィンドウに亀太郎を追加する。
 13: 
 14: ※四角形を描画する
 15: 四角形を描画するとは{
 16: 	整数型を新規作成して、iと名付ける。
 17: 	iに0を入れる。
 18: 	i<4である限り{
 19: 		亀太郎を50ドット進める。
 20: 		亀太郎を右に90度回す。
 21: 		iにi+1を入れる。
 22: 	}を繰り返す。
 23: }と定義する。
 24: 
 25: ※四角形を描く処理を呼び出す
 26: 四角形を描画する。

12.2.3 関数の作り方

12.2.3.1 関数定義と関数呼び出し

関数を使うためには、関数を定義し、その関数を呼び出す必要があります。

関数は一度定義すれば、同じ関数を何度も呼び出して使うことができます。

このプログラムでは13から21行目で関数を定義し、23行目で呼び出しています。

						
15:四角形を描画するとは{
16:	整数型を新規作成して、Iと名付ける。
17:	Iに0を入れる。
18:	I<4である限り{
19:		亀太郎を50ドット進める。
20:		亀太郎を右に90度回す。
21:		IにI+1を入れる。
22:	}を繰り返す。
23:}と定義する。
					
26: 四角形を描画する。
					

引数・戻り値なしの関数定義、関数呼び出しの記述は以下の通りです。関数名はサ変動詞(名詞+する)でなければなりません(要チェック)。

関数名とは{
	処理
}と定義する。
					
関数名。

12.2.3.2 関数定義の注意点

次のプログラムは、家を描くプログラムを書こうとして、失敗した例です。

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

リスト 12.2.3.2.1 家_エラー.dama
  1: ※プログラム名:家を描くプログラム(エラー)
  2: ※作成者:秋山 優
  3: ※作成日:2009.12.05
  4: 
  5: ※授業に必要なライブラリを取り込む。
  6: TurtleLibraryを参照する。
  7: 
  8: ※環境を初期化する。
  9: ウィンドウを初期化する。
 10: 亀を新規作成して、亀太郎と名付ける。
 11: ウィンドウに亀太郎を追加する。
 12: 
 13: ※家を描画する
 14: 家を描画するとは{
 15: 
 16: 	屋根を描画するとは{
 17: 		亀太郎を右に30度回す。
 18: 		整数型を新規作成してIと名付ける。
 19: 		Iに0を入れる。
 20: 		I<3である限り{
 21: 			亀太郎を50ドット進める。
 22: 			亀太郎を右に120度回す。
 23: 			IにI+1を入れる。
 24: 		}を繰り返す。
 25: 		亀太郎を右に60度回す。
 26: 	}と定義する。
 27: 
 28: 	壁を描画するとは{
 29: 		整数型を新規作成して、Iと名付ける。
 30: 		Iに0を入れる。
 31: 		I<4である限り{
 32: 			亀太郎を50ドット進める。
 33: 			亀太郎を右に90度回す。
 34: 			IにI+1を入れる。
 35: 		}を繰り返す。
 36: 	}と定義する。
 37: 
 38: 	屋根を描画する。
 39: 	壁を描画する。
 40: 
 41: }と定義する。
 42: 
 43: ※家を描画する処理を呼び出す
 44: 家を描画する。

このプログラムを実行しようとすると、コンパイルエラーが出てしまいます。

これは、関数の中に関数を定義しているためです。 このプログラムでは、家を描画する関数の中に、屋根や壁を描画する関数を定義しています。

図 12.2.3.2.1 関数定義のミス

言霊(やJAVA)では、関数の中に関数を定義することはできません。( 2章「プログラムの要素」参照 ) 正しい関数定義は以下のとおりです。

図 12.2.3.2.2 正しい関数定義

12.2.4 四角形を3つ描くプログラム

以下のプログラムは、四角形を描く関数を使って、四角形を3つ描くプログラムです。

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

リスト 12.2.4.1 四角形_3個.dama
  1: ※プログラム名:四角形を3個描くプログラム
  2: ※       (メソッド処理の順序)
  3: ※作成者:秋山 優
  4: ※作成日:2009.12.05
  5: 
  6: ※授業に必要なライブラリを取り込む。
  7: TurtleLibraryを参照する。
  8: 
  9: ※環境を初期化する。
 10: ウィンドウを初期化する。
 11: 亀を新規作成して、亀太郎と名付ける。
 12: ウィンドウに亀太郎を追加する。
 13: 
 14: ※四角形を描画する
 15: 四角形を描画するとは{
 16: 	整数型を新規作成して、iと名付ける。
 17: 	iに0を入れる。
 18: 	i<4である限り{
 19: 		亀太郎を50ドット進める。
 20: 		亀太郎を右に90度回す。
 21: 		iにi+1を入れる。
 22: 	}を繰り返す。
 23: }と定義する。
 24: 
 25: ※次の描く位置まで移動する
 26: 移動するとは{
 27: 	亀太郎の筆を無効化する。
 28: 	亀太郎を右に90度回す。
 29: 	亀太郎を60ドット進める。
 30: 	亀太郎を左に90度回す。
 31: 	亀太郎の筆を有効化する。
 32: }と定義する。
 33: 
 34: ※四角形を3つ描く
 35: 整数型を新規作成して、iと名付ける。
 36: iに0を入れる。
 37: i<3である限り{
 38: 	四角形を描画する。※四角形を描く処理を呼び出す
 39: 	移動する。    ※次に描く位置まで移動する処理を呼び出す
 40: 	iにi+1を入れる。
 41: }を繰り返す。

12.2.5 関数の処理の順序

関数が呼び出されると、プログラムの処理はその関数の処理に飛びます。 そして、関数が終了すると、関数呼び出し位置に返ってきます。

図 12.2.5.1 関数の処理の順序

四角形を3つ描くプログラムでは、まず、四角形を描く関数を呼び、 四角形を描き終わったら、次の描く位置まで移動する関数を呼び、 移動し終わったら、再び四角形を描く関数を呼び…という処理を3回繰り返しています。

やってみよう!

上向きの三角形を描く関数を作りましょう。

(はじめ、亀は上を向いていて、三角形を描き終わった後も、上向きに戻るものとします)

やってみよう!

三角形を描く関数と四角形を描く関数を使い、家を描く関数を作りましょう。

12.3 引数あり関数

12.3.1 引数とは

関数ブロック内で宣言された変数は、関数ブロック内でしか有効ではありません。 しかし、ある関数から他の関数を呼ぶときに、データを受け渡したいことがあります。 引数とは、関数ブロック外と、関数ブロック内でデータをやり取りする仕組みです。 引数を使うことで、関数ブロック外から、関数ブロック内にデータを受け取ることができます。

12.3.2 大きさを変えて四角形を描くプログラム

以下のプログラムは、引数を使って、関数の有効範囲外から四角形の長さを渡せるようにしたプログラムです。

入力された整数(実引数)を、関数に長さ(仮引数)として渡し、四角形を描いています。

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

リスト 12.3.2.1 四角形_引数あり.dama
  1: ※プログラム名:四角形を描くプログラム
  2: ※       (引数ありメソッドの練習)
  3: ※作成者:秋山 優
  4: ※作成日:2009.12.05
  5: 
  6: ※授業に必要なライブラリを取り込む。
  7: TurtleLibraryを参照する。
  8: 
  9: ※環境を初期化する。
 10: ウィンドウを初期化する。
 11: 亀を新規作成して、亀太郎と名付ける。
 12: ウィンドウに亀太郎を追加する。
 13: 
 14: ※四角形を描く
 15: 長さ(整数型)で四角形を描画するとは{
 16: 	整数型を新規作成して、iと名付ける。
 17: 	iに0を入れる。
 18: 	i<4である限り{
 19: 		亀太郎を長さドット進める。
 20: 		亀太郎を90度右に回す。
 21: 		iにi+1を入れる。
 22: 	}を繰り返す。
 23: }と定義する。
 24: 
 25: ※一辺の長さの入力を受け取る
 26: 整数型を新規作成して、入力と名付ける。
 27: コンソールに「一辺の長さを入力して下さい>」を出力する。
 28: コンソールから整数を受け取って、それを入力に入れる。
 29: 
 30: ※入力された長さを一辺の長さとして四角形を描く
 31: 入力で四角形を描画する。

12.3.3 引数あり関数の宣言と呼び出し

引数あり関数を使うためには、引数あり関数を宣言し、その関数を引数つきで呼び出す必要があります。

このプログラムでは16から24行目で関数を定義し、29行目で呼び出しています。

					
15:長さ(整数型)で四角形を描画するとは{
16:	整数型を新規作成して、iと名付ける。
17: 	iに0を入れる。
18: 	i<4である限り{
19:			亀太郎を長さドット進める。
20:			亀太郎を90度右に回す。
21:		iにi+1を入れる。
22: 	}を繰り返す。
23:}と定義する。
				
31: 入力で四角形を描画する。
				

このプログラム関数を呼び出す際に「入力」という変数を実引数として渡していますが、 「50で四角形を描画する。」や「100で四角形を描画する。」などのように、実際の値を実引数として渡すこともできます。

引数あり・戻り値なしの関数定義、関数呼び出しの記述は以下の通りです。助詞は、「は」「が」「を」「に」「で」「の」が使用可能です(要チェック)。

呼び出し部分の引数を実引数、宣言部分の引数を仮引数と呼びます。実引数(関数ブロック外にあるデータ)が、 仮引数(関数ブロック内で使える変数)に代入され、関数ブロック内で使えるようになります。

					
<仮引数名><(引数の型)><助詞><関数名>とは{
	処理
}と定義する。
				
<実引数名><助詞><関数名>。
やってみよう!

家を描く関数を改良し、大きさを変えられる家を描く関数を作りましょう。

12.4 関数を用いたプログラムの構造化

ここでは、以下のような構造を持った「窓付きの家を描くプログラム」を例に、プログラムの構造化について説明します。

「窓付きの家を描く」処理は、1レベル下の、「屋根を描く」「壁を描く」「窓を描く」処理の3つの処理で成り立っています。

「屋根を描く」処理はさらに1レベル下の、「三角形を描く」という処理で、「壁を描く」処理は「四角形を描く」処理で、 「窓を描く」処理は「窓を描く位置に移動する」という処理と「小さな四角形を描く」処理で成り立っています。

図 12.4.1 窓付きの家を描くプログラムの構造

12.4.1 窓付きの家を描くプログラム(関数なし)

次のプログラムは窓付きの家を描くプログラムです。このプログラムでは関数を使っていません。

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

リスト 12.4.1.1 家_窓付き1.dama
  1: ※プログラム名:窓付きの家を描くプログラム
  2: ※       (関数無し)
  3: ※作成者:岡田 健
  4: ※作成日:2010.05.01
  5: 
  6: ※授業に必要なライブラリを取り込む。
  7: TurtleLibraryを参照する。
  8: 
  9: ※環境を初期化する。
 10: ウィンドウを初期化する。
 11: 亀を新規作成して、亀太郎と名付ける。
 12: ウィンドウに亀太郎を追加する。
 13: 
 14: ※屋根を描く
 15: ※向きを調節する
 16: 亀太郎を右に30度回す。
 17: ※三角形を描く
 18: 整数型を新規作成して、iと名付ける。
 19: iに0を入れる。
 20: i<3である限り{
 21: 	亀太郎を80ドット進める。
 22: 	亀太郎を120度右に回す。
 23: 	iにi+1を入れる。
 24: }を繰り返す。
 25: ※向きを上向きに戻す
 26: 亀太郎を左に30度回す。
 27: 
 28: ※壁を描く
 29: ※向きを調節する
 30: 亀太郎を右に90度回す。
 31: ※四角形を描く
 32: 整数型を新規作成して、jと名付ける。
 33: jに0を入れる。
 34: j<4である限り{
 35: 	亀太郎を80ドット進める。
 36: 	亀太郎を右に90度回す。
 37: 	jにj+1を入れる。
 38: }を繰り返す。
 39: ※向きを上向きに戻す
 40: 亀太郎を左に90度回す。
 41: 
 42: ※窓を描く位置まで移動する
 43: ※前処理
 44: 亀太郎の筆を無効化する。
 45: ※右へ22ドット
 46: 亀太郎を90度右に回す。
 47: 亀太郎を22ドット進める。
 48: ※下へ22ドット
 49: 亀太郎を90度右に回す。
 50: 亀太郎を22ドット進める。
 51: ※後処理
 52: 亀太郎を180度右に回す。
 53: 亀太郎の筆を有効化する。
 54: 
 55: ※窓を描く
 56: ※向きを調節する
 57: 亀太郎を90度右に回す。
 58: 
 59: iに0を入れる。
 60: i<4である限り{
 61: 	※小さな四角形を描く
 62: 	jに0を入れる。
 63: 	j<4である限り{
 64: 		亀太郎を16ドット進める。
 65: 		亀太郎を右に90度回す。
 66: 		jにj+1を入れる。
 67: 	}を繰り返す。
 68: 	亀太郎を(16×2+4)ドット進める。
 69: 	亀太郎を90度右に回す。
 70: 	iにi+1を入れる。
 71: }を繰り返す。
 72: ※向きを上に戻す
 73: 亀太郎を左に90度回す。

12.4.2 窓付きの家を描くプログラム(1レベルを関数化)

次のプログラムでは、「窓付きの家を描く」処理は「屋根を描く」「壁を描く」「窓を描く」処理の3つの処理で成り立っていると考え、 「屋根を描く」「壁を描く」「窓を描く」関数を作成しました。

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

リスト 12.4.2.1 家_窓付き2.dama
  1: ※プログラム名:家付きの窓を描く(1レベルを関数化)
  2: ※作成者:秋山 優
  3: ※作成日:2009.12.05
  4: 
  5: ※授業に必要なライブラリを取り込む。
  6: TurtleLibraryを参照する。
  7: 
  8: ※環境を初期化する。
  9: ウィンドウを初期化する。
 10: 亀を新規作成して、亀太郎と名付ける。
 11: ウィンドウに亀太郎を追加する。
 12: 
 13: ※屋根を描く関数の定義
 14: 屋根を描画するとは{
 15: 	※向きを調整する
 16: 	亀太郎を右に30度回す。
 17: 
 18: 	※三角形を描く
 19: 	整数型を新規作成して、iと名付ける。
 20: 	iに0を入れる。
 21: 	i<3である限り{
 22: 		亀太郎を80ドット進める。
 23: 		亀太郎を120度右に回す。
 24: 		iにi+1を入れる。
 25: 	}を繰り返す。
 26: 
 27: 	※向きを上に戻す
 28: 	亀太郎を左に30度回す。
 29: }と定義する。
 30: 
 31: ※壁を描く関数の定義
 32: 壁を描画するとは{
 33: 	※向きを調整する
 34: 	亀太郎を右に90度回す。
 35: 
 36: 	※四角形を描く
 37: 	整数型を新規作成して、iと名付ける
 38: 	iに0を入れる。
 39: 	i<4である限り{
 40: 		亀太郎を80ドット進める。
 41: 		亀太郎を90度右に回す。
 42: 		iにi+1を入れる。
 43: 	}を繰り返す。
 44: 
 45: 	※向きを上に戻す
 46: 	亀太郎を左に90度回す。
 47: }と定義する。
 48: 
 49: ※窓を描く関数の定義
 50: 窓を描画するとは{
 51: 	※窓を描く位置まで移動
 52: 	※前処理
 53: 	亀太郎の筆を無効化する。
 54: 
 55: 	※右へ
 56: 	亀太郎を90度右に回す。
 57: 	亀太郎を22ドット進める。
 58: 
 59: 	※下へ
 60: 	亀太郎を90度右に回す。
 61: 	亀太郎を22ドット進める。
 62: 
 63: 	※後処理
 64: 	亀太郎を180度右に回す。
 65: 	亀太郎の筆を有効化する。
 66: 
 67: 	※窓を描く
 68: 	※向きを調整する
 69: 	亀太郎を右に90度回す。
 70: 
 71: 	整数型を新規作成して、iと名付ける
 72: 	iに0を入れる。
 73: 	i<4である限り{
 74: 
 75: 		※四角形を描く
 76: 		整数型を新規作成して、jと名付ける
 77: 		jに0を入れる。
 78: 		j<4である限り{
 79: 			亀太郎を16ドット進める。
 80: 			亀太郎を90度右に回す。
 81: 			jにj+1を入れる。
 82: 		}を繰り返す。
 83: 
 84: 		※次の描画位置に移動する
 85: 		亀太郎を(16×2+4)ドット進める。
 86: 		亀太郎を90度右に回す。
 87: 
 88: 		iにi+1を入れる。
 89: 	}を繰り返す。
 90: 		
 91: 	※向きを上に戻す
 92: 	亀太郎を90度左に回す。
 93: 
 94: }と定義する。
 95: 
 96: ※関数を呼び出す
 97: 屋根を描画する。
 98: 壁を描画する。
 99: 窓を描画する。

12.4.3 窓付きの家を描くプログラム(2レベルを関数化)

次のプログラムでは、「屋根を描く」処理は「三角形を描く」という処理で、「壁を描く」処理は「四角形を描く」処理で、 「窓を描く」処理は「窓を描く位置に移動する」という処理と「小さな四角形を描く」処理で成り立っていると考え、 このレベルの処理を関数化しました。

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

リスト 12.4.3.1 家_窓付き3.dama
  1: ※プログラム名:窓付きの家を描くプログラム(2レベルを関数化)
  2: ※作成者:秋山 優
  3: ※作成日:2009.12.05
  4: 
  5: ※授業に必要なライブラリを取り込む。
  6: TurtleLibraryを参照する。
  7: 
  8: ※環境を初期化する。
  9: ウィンドウを初期化する。
 10: 亀を新規作成して、亀太郎と名付ける。
 11: ウィンドウに亀太郎を追加する。
 12: 
 13: ※三角形を描画する関数の定義
 14: 三角形を描画するとは{
 15: 	※向きを調整する
 16: 	亀太郎を30度右に回す。
 17: 	
 18: 	※三角形を描画する
 19: 	整数型を新規作成して、iと名付ける。
 20: 	iに0を入れる。
 21: 	i<3である限り{
 22: 		亀太郎を80ドット進める。
 23: 		亀太郎を120度右に回す。
 24: 		iにi+1を入れる。
 25: 	}を繰り返す。
 26: 	
 27: 	※向きを上に戻す
 28: 	亀太郎を左に30度回す。
 29: }と定義する。
 30: 
 31: ※四角形を描画する関数の定義
 32: 四角形を描画するとは{
 33: 	整数型を新規作成して、iと名付ける。
 34: 	iに0を入れる。
 35: 	i<4である限り{
 36: 		亀太郎を80ドット進める。
 37: 		亀太郎を90度右に回す。
 38: 		iにi+1を入れる。
 39: 	}を繰り返す。
 40: }と定義する。
 41: 
 42: ※小さい四角形を描画する関数の定義
 43: 小さい四角形を描画するとは{
 44: 	整数型を新規作成して、iと名付ける。
 45: 	iに0を入れる。
 46: 	i<4である限り{
 47: 		亀太郎を16ドット進める。
 48: 		亀太郎を90度右に回す。
 49: 		iにi+1を入れる。
 50: 	}を繰り返す。
 51: }と定義する。
 52: 
 53: ※窓を描く位置まで移動する関数の定義
 54: 移動するとは{
 55: 	※前処理
 56: 	亀太郎の筆を無効化する。
 57: 
 58: 	※右へ22
 59: 	亀太郎を右に90度回す。
 60: 	亀太郎を22ドット進める。
 61: 
 62: 	※下へ22
 63: 	亀太郎を右に90度回す。
 64: 	亀太郎を22ドット進める。
 65: 
 66: 	※後処理
 67: 	亀太郎を180度右に回す。
 68: 	亀太郎の筆を有効化する。
 69: }と定義する。
 70: 
 71: ※屋根を描画する関数の定義
 72: 屋根を描画するとは{
 73: 	三角形を描画する。
 74: }と定義する。
 75: 
 76: ※壁を描画する関数の定義
 77: 壁を描画するとは{
 78: 	※向きを調整する
 79: 	亀太郎を90度右に回す。
 80: 	※四角形を描画する関数を呼び出す
 81: 	四角形を描画する。
 82: 	※向きを上に戻す
 83: 	亀太郎を左に90度回す。
 84: }と定義する。
 85: 
 86: ※窓を描画する関数の定義
 87: 窓を描画するとは{
 88: 	※窓を描く位置まで移動する関数を呼び出す
 89: 	移動する。
 90: 
 91: 	※窓を描く
 92: 	亀太郎を右に90度回す。
 93: 	整数型を新規作成して、iと名付ける。
 94: 	iに0を入れる。
 95: 	i<4である限り{
 96: 		※小さい四角形を描画する関数を呼び出す
 97: 		小さい四角形を描画する。
 98: 		亀太郎を(16×2+4)ドット進める。
 99: 		亀太郎を右に90度回す。
100: 		iにi+1を入れる。
101: 	}を繰り返す。
102: 
103: 	亀太郎を左に90度回す。
104: }と定義する。
105: 
106: ※関数を呼び出して窓付きの家を描画する
107: 屋根を描画する。
108: 壁を描画する。
109: 窓を描画する。

12.5 引数を用いた関数の抽象化

12.5.1 窓付きの家を描くプログラム(引数を用いた、四角形を描く関数の抽象化)

次のプログラムでは、引数あり関数を使い、「壁を描く」処理で使っていた大きい四角形と 「窓を描く」処理の中で使っていた小さな四角形を「四角形を描く」というひとつの関数で描けるようにしています。

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

リスト 12.5.1.1 家_窓付き4.dama
  1: ※プログラム名:窓付きの家を描くプログラム(引数を用いた四角形を描く関数の抽象化)
  2: ※作成者:秋山 優
  3: ※作成日:2009.12.05
  4: 
  5: ※授業に必要なライブラリを取り込む。
  6: TurtleLibraryを参照する。
  7: 
  8: ※環境を初期化する。
  9: ウィンドウを初期化する。
 10: 亀を新規作成して、亀太郎と名付ける。
 11: ウィンドウに亀太郎を追加する。
 12: 
 13: ※三角形を描画する関数の定義
 14: サイズ(整数型)で三角形を描画するとは{
 15: 	※向きを調整する
 16: 	亀太郎を30度右に回す。
 17: 	
 18: 	※三角形を描画する
 19: 	整数型を新規作成して、iと名付ける。
 20: 	iに0を入れる。
 21: 	i<3である限り{
 22: 		亀太郎をサイズドット進める。
 23: 		亀太郎を120度右に回す。
 24: 		iにi+1を入れる。
 25: 	}を繰り返す。
 26: 	
 27: 	※向きを上に戻す
 28: 	亀太郎を左に30度回す。
 29: }と定義する。
 30: 
 31: ※四角形を描画する関数の定義
 32: サイズ(整数型)で四角形を描画するとは{
 33: 	整数型を新規作成して、iと名付ける。
 34: 	iに0を入れる。
 35: 	i<4である限り{
 36: 		亀太郎をサイズドット進める。
 37: 		亀太郎を90度右に回す。
 38: 		iにi+1を入れる。
 39: 	}を繰り返す。
 40: }と定義する。
 41: 
 42: ※窓を描く位置まで移動する関数の定義
 43: 距離(整数型)を移動するとは{
 44: 	※前処理
 45: 	亀太郎の筆を無効化する。
 46: 
 47: 	※右へ22
 48: 	亀太郎を右に90度回す。
 49: 	亀太郎を距離ドット進める。
 50: 
 51: 	※下へ22
 52: 	亀太郎を右に90度回す。
 53: 	亀太郎を距離ドット進める。
 54: 
 55: 	※後処理
 56: 	亀太郎を180度右に回す。
 57: 	亀太郎の筆を有効化する。
 58: }と定義する。
 59: 
 60: ※屋根を描画する関数の定義
 61: 屋根を描画するとは{
 62: 	80で三角形を描画する。
 63: }と定義する。
 64: 
 65: ※壁を描画する関数の定義
 66: 壁を描画するとは{
 67: 	※向きを調整する
 68: 	亀太郎を90度右に回す。
 69: 	※四角形を描画する関数を呼び出す
 70: 	80で四角形を描画する。
 71: 	※向きを上に戻す
 72: 	亀太郎を左に90度回す。
 73: }と定義する。
 74: 
 75: ※窓を描画する関数の定義
 76: 窓を描画するとは{
 77: 	※窓を描く位置まで移動する関数を呼び出す
 78: 	22を移動する。
 79: 
 80: 	※窓を描く
 81: 	亀太郎を右に90度回す。
 82: 	整数型を新規作成して、iと名付ける。
 83: 	iに0を入れる。
 84: 	i<4である限り{
 85: 		※小さい四角形を描画する関数を呼び出す
 86: 		16で四角形を描画する。
 87: 		亀太郎を(16×2+4)ドット進める。
 88: 		亀太郎を右に90度回す。
 89: 		iにi+1を入れる。
 90: 	}を繰り返す。
 91: 
 92: 	亀太郎を左に90度回す。
 93: }と定義する。
 94: 
 95: ※関数を呼び出して窓付きの家を描画する
 96: 屋根を描画する。
 97: 壁を描画する。
 98: 窓を描画する。

12.5.2 窓付きの家を描くプログラム(引数を用いた、多角形を描く関数の抽象化)

次のプログラムでは「屋根を描く」処理で使っていた三角形と、「壁を描く」「窓を描く」処理で使っていた四角形を 「多角形を描く」というひとつの関数で描けるようにしています。

引数を複数指定する際は、関数宣言時に仮引数を助詞「と」で連結します。関数を呼び出す際も、同様に「と」で引数を連結して記述します。(要チェック)

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

リスト 12.5.2.1 家_窓付き5.dama
  1: ※プログラム名:窓付きの家を描くプログラム(引数による多角形を描く関数の抽象化)
  2: ※作成者:秋山 優
  3: ※作成日:2009.12.05
  4: 
  5: ※授業に必要なライブラリを取り込む。
  6: TurtleLibraryを参照する。
  7: 
  8: ※環境を初期化する。
  9: ウィンドウを初期化する。
 10: 亀を新規作成して、亀太郎と名付ける。
 11: ウィンドウに亀太郎を追加する。
 12: 
 13: ※指定した角数の正多角形を描画する関数の定義
 14: n(整数型)とサイズ(整数型)で多角形を描画するとは{
 15: 
 16: 	※向きを調整する
 17: 	整数型を新規作成して、角と名付ける。
 18: 	角に(360÷n)を入れる。
 19: 
 20: 	亀太郎を(角-90)度右に回す。
 21: 
 22: 	※多角形を描画する
 23: 	整数型を新規作成して、iと名付ける。
 24: 	iに0を入れる。
 25: 	i<nである限り{
 26: 		亀太郎をサイズドット進める。
 27: 		亀太郎を右に角度回す。
 28: 		iにi+1を入れる。
 29: 	}を繰り返す。
 30: 
 31: 	※向きを上に戻す
 32: 	亀太郎を(角-90)度左に回す。
 33: }と定義する。
 34: 
 35: ※指定された方向にペンを上げて亀を移動させる関数の定義
 36: 方向(整数型)と距離(整数型)で亀を移動するとは{
 37: 	亀太郎の筆を無効化する。
 38: 	亀太郎を方向度右に回す。
 39: 	亀太郎を距離ドット進める。
 40: 	亀太郎を方向度左に回す。
 41: 	亀太郎の筆を有効化する。
 42: }と定義する。
 43: 
 44: ※窓を描く位置まで移動する関数の定義
 45: 距離(整数型)で指定位置に移動するとは{
 46: 	※右へ
 47: 	90と22で亀を移動する。
 48: 	※下へ
 49: 	180と22で亀を移動する。
 50: }と定義する。
 51: 
 52: ※屋根を描画する関数の定義
 53: 屋根を描画するとは{
 54: 	※三角形を描画する
 55: 	3と80で多角形を描画する。
 56: }と定義する。
 57: 
 58: ※壁を描画する関数の定義
 59: 壁を描画するとは{
 60: 	亀太郎を右に90度回す。
 61: 	4と80で多角形を描画する。
 62: 	亀太郎を90度左に回す。
 63: }と定義する。
 64: 
 65: ※窓を描画する関数の定義
 66: 窓を描画するとは{
 67: 	※窓を描画する位置まで移動する
 68: 	22で指定位置に移動する。
 69: 
 70: 	※窓を描画する
 71: 	亀太郎を90度右に回す。
 72: 	整数型を新規作成して、iと名付ける。
 73: 	iに0を入れる。
 74: 	i<4である限り{
 75: 		4と16で多角形を描画する。
 76: 		亀太郎を(16×2+4)ドット進める。
 77: 		亀太郎を右に90度回す。
 78: 		iにi+1を入れる。
 79: 	}を繰り返す。
 80: 
 81: 	亀太郎を左に90度回す。
 82: }と定義する。
 83: 
 84: ※家を描画する
 85: 屋根を描画する。
 86: 壁を描画する。
 87: 窓を描画する。

12.6 課題

12.6.1 問題1-1:中心角を指定して円弧を描く関数を作ろう

「中心角(整数型)の円弧を描画する。」のように、中心角を指定して円弧を描く関数を作ろう。

(ヒント:中心角が360ならば円に、180ならば半円に、1ならば点のようになります。以下に、120度の場合と、300度の場合の例を示します)

図 12.6.1.1 円弧を描く関数
図 12.6.1.2 円弧を描く関数2

12.6.2 問題1-2:円弧を描く関数を使って猫の目を描こう

円弧を描く関数を使って、「猫目を描画する。」のように猫の目を描く関数を作ろう。

(ヒント:猫の目を描くには、レモン型を描く関数「レモンを描画する。」を作って、それを2つ並べるとよい。)

図 12.6.2.1 レモン型を描く関数
図 12.6.2.2 猫の目を描く関数

12.6.3 問題1-3:円弧を描く関数を使って蝶を描こう

円弧を描く関数を使って、「蝶を描画する。」のように蝶を描く関数を作ろう。

(ヒント:円弧を描く関数のほかにも、レモン型を描く関数などを部品として使うと楽に描ける)

図 12.6.3.1 蝶を描く関数

12.6.4 問題1-4:円弧を描く関数を使って花を描こう

円弧を描く関数を使って、「花を描画する。」のように花を描く関数を作ろう。

(ヒント:レモン型を描く関数などを部品として使うと楽に描ける)

図 12.6.4.1 花を描く関数

12.6.5 問題2:入力によって猫の目、蝶、花を描き分けるプログラムを作ろう

1を入力したら猫の目を、2を入力したら蝶を、3を入力したら花を描くプログラムを作ろう。

12.7 おまけ問題

関数が自分自身を呼び出す処理を、再帰関数呼び出しと言う。

これは、発展的で面白いプログラミングテクニックである。

12.7.1 再帰を使って木を描くサンプルプログラム

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

リスト 12.7.1.1 木.dama
  1: ※プログラム名:再帰を使って木を描くプログラム
  2: ※作成者:秋山 優
  3: ※作成日:2009.12.05
  4: 
  5: ※授業に必要なライブラリを取り込む。
  6: TurtleLibraryを参照する。
  7: 
  8: ※環境を初期化する。
  9: ウィンドウを初期化する。
 10: 亀を新規作成して、亀太郎と名付ける。
 11: ウィンドウに亀太郎を追加する。
 12: 
 13: 亀太郎を100ドット戻す。※木を描画する位置まで移動する
 14: 
 15: 
 16: ※関数開始のデバッグ出力をする
 17: 出力枝数(整数型)と出力長さ(整数型)で開始デバッグを出力するとは{
 18: 	整数型を新規作成して、Iと名付ける。
 19: 	Iに0を入れる。
 20: 	I<出力枝数である限り{
 21: 		※コンソールにタブを出力する。
 22: 		IにI+1を入れる。
 23: 	}を繰り返す。
 24: 
 25: 	コンソールに「木を描く(枝分かれの数:)」を出力する。
 26: 	コンソールに出力枝数を出力する。
 27: 	コンソールに「幹の長さ:」を出力する。
 28: 	コンソールに「出力長さ」を出力する。
 29: 	コンソールに「)。」を出力する。
 30: 	コンソールに改行を出力する。
 31: 
 32: }と定義する。
 33: 
 34: ※関数終了のデバッグ出力をする
 35: 描画枝数(整数型)で終了デバッグを出力するとは{
 36: 	整数型を新規作成して、Iと名付ける。
 37: 	Iに0を入れる。
 38: 	I<描画枝数である限り{
 39: 		コンソールにタブを出力する。
 40: 		IにI+1を入れる。
 41: 	}を繰り返す。
 42: 
 43: 	コンソールに「//」を出力する。
 44: 	コンソールに改行を出力する。
 45: }と定義する。
 46: 
 47: 
 48: ※木を描画する関数の定義
 49: 枝数(整数型)と長さ(整数型)で木を描画するとは{
 50: 
 51: 	※関数開始のデバッグ出力をする
 52: 	枝数と長さで開始デバッグを出力する。
 53: 
 54: 	枝数=6であるならば{
 55: 		亀太郎を長さドット進める。
 56: 		亀太郎を長さドット戻す。
 57: 	}をして、そうでないならば{
 58: 		亀太郎を長さドット進める。
 59: 
 60: 		※右の枝を描く
 61: 		亀太郎を右に30度回す。
 62: 		(枝数+1)と(長さ÷2)で木を描画する。
 63: 		亀太郎を左に30度回す。
 64: 
 65: 		※左の枝を描く
 66: 		亀太郎を左に30度回す。
 67: 		(枝数+1)と(長さ÷2)で木を描画する。
 68: 		亀太郎を右に30度回す。
 69: 
 70: 		亀太郎を長さドット戻す。
 71: 	}をする。
 72: 
 73: 	※関数終了のデバッグ出力をする
 74: 	枝数で終了デバッグを出力する。
 75: }と定義する。
 76: 
 77: 1と100で木を描画する。※枝分かれの数を1とし、幹の長さを100として木を描く

12.7.2 おまけ問題1:再帰を使って自然な木を描くプログラム

木を描くサンプルプログラムを乱数を使うように改造して、自然な木を描くプログラムにしよう。

枝の生える角度と、長さを乱数にします。

【自然な木に見せるためのヒント】

図 12.7.2.1 自然な木

12.7.3 おまけ問題2:再帰を使ってコッホ曲線を描くプログラム

図 12.7.3.1 コッホ曲線

ノーヒント