13 プログラムの部品化(2)(戻り値)

13.1 学習目標

13.2 入力・処理・出力

累乗計算プログラムを例に、プログラムと関数の入力・処理・出力について学びます。

13.2.1 プログラムの入出力

13.2.1.1 累乗計算プログラムの入出力

次のプログラムは、ユーザから底と指数の入力を受け取り、累乗を計算するプログラムです。

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

リスト 13.2.1.1.1 累乗計算.dama
  1: ※プログラム名:累乗計算プログラム
  2: ※作成者:秋山 優
  3: ※作成日:2009.12.16
  4: 
  5: ※授業に必要なライブラリを取り込む。
  6: TurtleLibraryを参照する。
  7: 
  8: ※累乗を計算する関数の定義
  9: 底(整数型)と指数(整数型)で累乗を計算する(整数型)とは{
 10: 	※累乗数の初期値を、数の0乗(1)に設定する
 11: 	整数型を新規作成して、累乗数と名付ける。
 12: 	累乗数に1を入れる。
 13: 
 14: 	※累乗を計算する
 15: 	整数型を新規作成して、xと名付ける。
 16: 	x<指数である限り{
 17: 		累乗数に累乗数×底を入れる。
 18: 		xにx+1を入れる。
 19: 	}を繰り返す。
 20: 
 21: 	累乗数を返す。
 22: }と定義する。
 23: 
 24: 整数型を新規作成して、底と名付ける。
 25: 整数型を新規作成して、指数と名付ける。
 26: 整数型を新規作成して、累乗数と名付ける。
 27: 
 28: ※アプリケーションの開始を知らせる
 29: コンソールに「累乗計算プログラムを開始します」を出力する。
 30: コンソールに改行を出力する。
 31: 
 32: ※底の入力を受け付ける
 33: コンソールに「底を入力して下さい」を出力する。
 34: コンソールに改行を出力する。
 35: コンソールから整数を受け取って、それを底に入れる。
 36: 
 37: ※指数の入力を受け付ける
 38: コンソールに「指数を入力して下さい」を出力する。
 39: コンソールに改行を出力する。
 40: コンソールから整数を受け取って、それを指数に入れる。
 41: 
 42: ※累乗数を計算し、計算結果を累乗数という変数に書き込む
 43: 底と指数で累乗を計算して、それを累乗数に入れる。
 44: 
 45: ※累乗数を出力する
 46: コンソールに「」+底+「の」+指数+「乗は」+累乗数+「です。」を出力する。
 47: コンソールに改行を出力する。
 48: 
 49: ※アプリケーションの終了を知らせる
 50: コンソールに「累乗計算プログラムを週力します」を出力する。

このプログラムの入力・処理・出力を図に表すと以下のようになります。

矢印はデータの流れを、四角は処理を示します。

図 13.2.1.1.1 累乗計算関数の入出力

13.2.1.2 一般的なプログラムの入出力

プログラムは一般的に、入力・処理・出力の構造を持っています。

たとえば、7章「はじめてのCUIプログラム」の、BMI値算出プログラムの入力・処理・出力を図に表すと以下のようになります。

図 13.2.1.2.1 累乗計算関数の入出力
やってみよう!

7章の練習問題それぞれについて、入力・処理・出力を表す図を描いてみましょう。

13.2.2 関数の入出力

13.2.2.1 累乗を計算する関数の入出力

累乗を計算する関数は、整数型の値を返す、戻り値あり関数です。 引数として底・指数を受け取り、累乗数を返しています。

						
 42:	※累乗数を計算し、計算結果を累乗数という変数に書き込む
 43:	底と指数で累乗を計算して、それを累乗数に入れる。

					
						
 8:	※累乗を計算する関数の定義
 9:	底(整数型)と指数(整数型)で累乗を計算する(整数型)とは{
 10:		※累乗数の初期値を、数の0乗(1)に設定する
 11:		整数型を新規作成して、累乗数と名付ける。
 12:		累乗数に1を入れる。
 13:
 14:		※累乗を計算する
 15:		整数型を新規作成して、xと名付ける。
 16:		x<指数である限り{
 17:			累乗数に累乗数×底を入れる。
 18:			xにx+1を入れる。
 19:		}を繰り返す。
 20:
 21:		累乗数を返す。
 22:	}と定義する。

					

関数も、プログラムと同様に入力・処理・出力の構造を持っています。

この関数の入力・処理・出力を図に表すと、以下のようになります。

図 13.2.2.1.1 累乗計算関数の入出力

13.2.2.2 一般的な関数の入出力

戻り値とは

前の章「プログラムの部品化(1)」では、関数と、引数について学びました。 引数は、関数ブロック外から渡される値= 入力 でした。

引数は、呼び出し元の関数から呼び出した関数に、データを受け渡したいという要求をかなえる仕組みでした。 逆に、呼び出された関数が処理した結果を呼び出し元に受け渡したい、という場合もあります。 これをかなえる仕組みが、戻り値です。

戻り値は、呼び出し元に戻す値= 出力 です。

図 .1 関数の入出力
このように、関数も、入力・処理・出力の構造を作ることができます。 引数は、複数指定することができますが、戻り値は必ずひとつです。

戻り値あり関数の定義と呼び出し

戻り値あり関数の定義の仕方は、次の通りです。

戻り値あり関数では、「<戻り値>を返す。」命令を書いたところで関数の出力は決まり、関数の処理を抜けます。 したがって、「<戻り値>を返す。」命令の後に命令を書いても、実行されることはありません(「この文に制御が移ることはありません」というエラーが出ます)。

							
<仮引数名>(引数の型)<助詞><関数名>(戻り値の型)とは{
	<戻り値>を返す。
}と定義する。
						

戻り値あり関数の呼び出し方は、次の通りです(引数あり関数と同様、関数名はサ変動詞(名詞+する)で終わるようにしましょう)。

							
<引数名>(引数の型)<助詞><関数名>。

						
やってみよう!

税抜価格を引数とし、税込価格を戻り値とする関数【税抜き価格(整数型)から税込価格を計算する(整数型)】を作り、 税抜価格を入力すると、「税抜価格○○円の品物の税込価格は○○円です」と出力するプログラムを作りましょう。

整数に小数をかけると、実数型になります。 戻り値は整数型なので、整数型にキャストしてください。 整数型にキャストすると、小数点以下は切り捨てられます。

(一般の事業者の場合、消費税の計算は切捨て、四捨五入、切り上げのいずれかを 事業者自身が選択してよいことになっています。切捨て、もしくは四捨五入をするところが多いようです。 この問題では、消費税の小数点以下は切り捨てるものとして扱ってください。)

13.3 入出力を持つ関数を用いたプログラムの構造化

西暦和暦変換プログラムを例に、プログラムの部品化と戻り値について学びます。 西暦和暦変換プログラムは、西暦を入力として受け取り、和暦を出力するプログラムです。 西暦和暦変換プログラムの入力・処理・出力を表す図は以下の通りです。

図 13.3.1 西暦和暦変換プログラムの入出力

西暦和暦変換プログラムの中には、さらに入力・処理・出力の構造が入っています。 以下の図は、西暦和暦変換プログラムの入力・処理・出力の階層構造を表す図です。

図 13.3.2 西暦和暦変換プログラムの入出力

西暦和暦変換プログラムの全体構造は、以下のようになっています。

「西暦を和暦に変換する」という処理は、「アプリケーションの開始を知らせる」 「西暦を和暦に変換する」「アプリケーションの終了を知らせる」という1レベル下の処理から成り立っています。

「西暦を和暦に変換する」という処理は、さらに1レベル下の、 「西暦を入力する」「西暦を和暦に変換する」「変換結果を出力する」という処理から成り立っています。

図 13.3.3 西暦和暦変換プログラムの構造

13.3.1 西暦和暦変換プログラム(関数なし)

次のプログラムは西暦を和暦に変換するプログラムです。 このプログラムでは、関数を使っていません。

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

リスト 13.3.1.1 西暦和暦変換1.dama
  1: ※プログラム名:西暦和暦変換プログラム(関数なし)
  2: ※作成者:秋山 優
  3: ※作成日:2009.12.16
  4: 
  5: ※授業に必要なライブラリを取り込む。
  6: TurtleLibraryを参照する。
  7: 
  8: ※アプリケーションの開始を知らせる
  9: コンソールに「西暦和暦変換プログラムを開始します。」を出力する。
 10: コンソールに改行を出力する。
 11: 
 12: ※西暦を和暦に変換する。
 13: 整数型を新規作成して、西暦と名付ける。
 14: 文字列型を新規作成して、和暦と名付ける。
 15: 
 16: ※西暦を入力する
 17: コンソールに「西暦を入力して下さい。」を出力する。
 18: コンソールから整数を受け取って、それを西暦に入れる。
 19: 
 20: ※西暦を和暦に変換する。
 21: 西暦≧1989であるならば{
 22: 	和暦に「平成」+(西暦-1988)を入れる。
 23: }をして、西暦≧1926であるならば{
 24: 	和暦に「昭和」+(西暦-1925)を入れる。
 25: }をして、そうでないならば{
 26: 	和暦に「不明」を入れる。
 27: }をする。
 28: 
 29: ※変換結果を出力する
 30: コンソールに「西暦」+西暦+「年は」+和暦+「年です。」を出力する。
 31: コンソールに改行を出力する。
 32: 
 33: ※アプリケーションの終了を知らせる
 34: コンソールに「西暦和暦変換プログラムを終了します。」を出力する。

13.3.2 西暦和暦変換プログラム(1レベルを関数化)

次のプログラムでは、1レベルを関数化しています。

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

リスト 13.3.2.1 西暦和暦変換2.dama
  1: ※プログラム名:西暦和暦変換プログラム(1レベルを関数化)
  2: ※作成者:秋山 優
  3: ※作成日:2009.12.16
  4: 
  5: ※授業に必要なライブラリを取り込む。
  6: TurtleLibraryを参照する。
  7: 
  8: ※西暦を和暦に変換する関数の定義
  9: 西暦を和暦に変換するとは{
 10: 
 11: 	整数型を新規作成して、西暦と名付ける。
 12: 	文字列型を新規作成して、和暦と名付ける。
 13: 	
 14: 	※西暦を入力する
 15: 	コンソールに「西暦を入力してください」を出力する。
 16: 	コンソールから整数を受け取って、それを西暦に入れる。
 17: 
 18: 	※西暦を和暦に変換する。
 19: 	西暦≧1989であるならば{
 20: 		和暦に「平成」+(西暦-1988)を入れる。
 21: 	}をして、西暦≧1926であるならば{
 22: 		和暦に「昭和」+(西暦-1925)を入れる。
 23: 	}をして、そうでないならば{
 24: 		和暦に「不明」を入れる。
 25: 	}をする。
 26: 
 27: 	※変換結果を出力する
 28: 	コンソールに「西暦」+西暦+「年は」+和暦+「年です。」を出力する。
 29: 	コンソールに改行を出力する。
 30: 
 31: }と定義する。
 32: 
 33: ※アプリケーションの開始を知らせる関数の定義
 34: 開始メッセージを表示するとは{
 35: 	コンソールに「西暦和暦変換プログラムを開始します」を出力する。
 36: 	コンソールに改行を出力する。
 37: }と定義する。
 38: 
 39: ※アプリケーションの終了を知らせる関数の定義
 40: 終了メッセージを表示するとは{
 41: 	コンソールに「西暦和暦変換プログラムを終了します」を出力する。
 42: }と定義する。
 43: 
 44: ※関数を呼び出す
 45: 開始メッセージを表示する。
 46: 西暦を和暦に変換する。
 47: 終了メッセージを表示する。

13.3.3 西暦和暦変換プログラム(2レベルを関数化)

次のプログラムでは、2レベルを関数化しています。

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

リスト 13.3.3.1 西暦和暦変換3.dama
  1: ※プログラム名:西暦和暦変換プログラム(2レベルを関数化)
  2: ※作成者:秋山 優
  3: ※作成日:2009.12.16
  4: 
  5: ※授業に必要なライブラリを取り込む。
  6: TurtleLibraryを参照する。
  7: 
  8: ※西暦年を取得する関数を定義する
  9: 西暦年を取得する(整数型)とは{
 10: 	整数型を新規作成して、西暦と名付ける。
 11: 	コンソールに「西暦を入力してください」を出力する。
 12: 	コンソールから整数を受け取って、それを西暦に入れる。
 13: 	西暦を返す。
 14: }と定義する。
 15: 
 16: ※和暦変換する関数を定義する
 17: 西暦(整数型)を和暦変換する(文字列型)とは{
 18: 	文字列型を新規作成して、和暦と名付ける。
 19: 	西暦≧1989であるならば{
 20: 		「平成」+(西暦-1988)を和暦に入れる。
 21: 	}をして、西暦≧1926であるならば{
 22: 		「昭和」+(西暦-1925)を和暦に入れる。
 23: 	}をして、そうでないならば{
 24: 		「不明」を和暦に入れる。
 25: 	}をする。
 26: 	
 27: 	和暦を返す。
 28: }と定義する。
 29: 
 30: ※変換結果を出力する関数を定義する
 31: 西暦(整数型)と和暦(文字列型)の変換結果を出力するとは{
 32: 	コンソールに「西暦」+西暦+「年は」+和暦+「年です。」を出力する。
 33: 	コンソールに改行を出力する。
 34: }と定義する。
 35: 
 36: ※西暦を和暦に変換して変換結果を表示する関数の定義
 37: 西暦を和暦に変換するとは{
 38: 	整数型を新規作成して、西暦と名付ける。
 39: 	文字列型を新規作成して、和暦と名付ける。
 40: 
 41: 	西暦年を取得して、それを西暦に入れる。
 42: 	西暦を和暦変換して、それを和暦に入れる。
 43: 	西暦と和暦の変換結果を出力する。
 44: }と定義する。
 45: 
 46: ※アプリケーションの開始を知らせる関数の定義
 47: 開始メッセージを表示するとは{
 48: 	コンソールに「西暦和暦変換プログラムを開始します」を出力する。
 49: 	コンソールに改行を出力する。
 50: }と定義する。
 51: 
 52: ※アプリケーションの終了を知らせる関数の定義
 53: 終了メッセージを表示するとは{
 54: 	コンソールに「西暦和暦変換プログラムを終了します」を出力する。、
 55: 	コンソールに改行を出力する。
 56: }と定義する。
 57: 
 58: ※関数を呼び出す
 59: 開始メッセージを表示する。
 60: 西暦を和暦に変換する。
 61: 終了メッセージを表示する。

13.4 練習問題

「はじめてのCUIプログラム」で作ったCUIプログラムを、関数を使って書き直しましょう。

仕様は以下を参考にしてください(関数の作り方に関する指示が追加されています)。

13.4.1 問題1:体型評価プログラムを作ろう

13.4.1.1 概要

このプログラムは,身長と体重の入力を実数で受け付ける. その入力をもとにBMI指数と,その値から評価されたコメントを出力する.

13.4.1.2 機能

  1. プログラムの起動時および終了時に、その旨をユーザに伝えるメッセージを出力する。
  2. 身長と体重の入力を受け取り、BMI指数と、その値から評価されたコメントを出力する。

13.4.1.3 エラー処理

文字など処理不可能な値が入力されたときの処理は、行わなくてよい.

13.4.1.4 プログラム設計条件

  1. 入出力は起動したコンソールから行う(CUIプログラムである)。
  2. 必ず次の入出力(身長と体重を入力とし、小数型のBMI値を出力とする)を持つ関数を作ること。
  3. 上記以外の部分の関数化はプログラマに一任する。

13.4.2 問題2:恋愛占いプログラムを作ろう

13.4.2.1 概要

このプログラムは、男女の名前を入力すると、 その恋愛成就確率を百分率で判定し、コメント付で出力する。

13.4.2.2 機能

  1. プログラムの起動時および終了時に、その旨をユーザに伝えるメッセージを出力する。
  2. 男女の名前の入力を受け取り、恋愛成就確率をコメント付で出力する。

13.4.2.3 エラー処理

処理不可能な値が入力されたときの処理は、行わなくてよい。

13.4.2.4 プログラム設計条件

  1. 入出力は起動したコンソールから行う(CUIプログラムである)。
  2. 必ず次の入出力(女性の名前を整数に変換したものと、男性の名前を整数に変換したものを入力とし、小数型の恋愛成就率を出力とする)を持つ関数を作ること。
  3. 上記以外の部分の関数化はプログラマに一任する。

13.4.3 問題3:単位取得状況評価プログラムを作ろう

13.4.3.1 概要

このプログラムは、SFC生の単位取得の状況の入力を受け取り、 それを評価し、卒業するためのコメントを出力する。

13.4.3.2 機能

  1. プログラムの起動時および終了時に、その旨をユーザに伝えるメッセージを出力する。
  2. 経過した学期数と現在取得した単位数の入力を受け取り、その値から評価されたコメントを出力する。

13.4.3.3 エラー処理

文字など処理不可能な値が入力されたときの処理は、行わなくてよい。

13.4.3.4 プログラム設計条件

  1. 入出力は起動したコンソールから行う(CUIプログラムである)。
  2. 必ず次の入出力(経過した学期数と取得した単位数を入力とし、小数型の「今後1学期あたりに取らなければならない単位数」を出力とする)を持つ関数を作ること。
  3. 上記以外の部分の関数化はプログラマに一任する。

13.5 発展問題

13.5.1 問題1:脳トレ 論プロ風

13.5.1.1 概要

ユーザが計算問題を解くことで脳を鍛えるソフトウエアである。 このプログラムは、足し算の計算問題を自動生成して、何問か出題し、そのつど答えあわせをする。

13.5.1.2 機能

  1. プログラムの起動時、および終了時にその旨をユーザに知らせるメッセージを出力する。
  2. 足し算の計算問題を生成する。

    各数字の桁数は一桁の整数である(答えは任意の桁数の整数とする)

  3. 出題し、答えあわせをする。
  4. 2)、3)を連続で10回行い、最後に正答率を出力する。

13.5.1.3 エラー処理

処理不可能な値が入力されたときの処理は、行わなくてよい。

13.5.1.4 プログラム設計条件

  1. 入出力は起動したコンソールから行う(CUIプログラムである)。
  2. 関数を作る場所は自由であるが、引数、戻り値の双方を持つ関数を一つ以上含むこと。
  3. 上記以外の部分の関数化はプログラマに一任する。

13.5.2 問題2:マイホーム大作戦

13.5.2.1 概要

マイホームローンの返済計算を行うプログラムである。ユーザは家を買うときに利用することを想定する。 システムは、家の値段と利率、月々の返済金額を入力として受け取り、 返済が終わるまでにかかる期間を計算し、コメントとともに出力する。

13.5.2.2 機能

  1. プログラムの起動時および終了時に、その旨をユーザに伝えるメッセージを出力する。
  2. 家の値段とローン年数、利率、月々の返済金額を入力として受け取り、月々の返済金額を計算して出力する。

13.5.2.3 エラー処理

処理不可能な値が入力されたときの処理は、行わなくてよい。

13.5.2.4 プログラム設計条件

  1. 入出力は起動したコンソールから行う(CUIプログラムである)。
  2. 関数を作る場所は自由であるが、引数、戻り値の双方を持つ関数を一つ以上含むこと。
  3. 上記以外の部分の関数化はプログラマに一任する。

13.5.3 問題3:ザ・バイナリサーチ

13.5.3.1 概要

「数あてゲーム」である。システムはまず,1-1000までの整数をランダムに選ぶ(表示しない)。 ユーザはこの数をなるべく少ない回答で当てるのが目的である.ユーザは推測した数を入力し、 システムは数が当っていたら、あたったことをユーザに知らせて終了、 外れていたら、大きすぎるのか、小さすぎるのかをユーザに知らせて再入力を求める。

13.5.3.2 機能

  1. プログラムの起動時、および終了時にその旨をユーザに知らせるメッセージを出力する。
  2. 整数をランダムに選ぶ。
  3. 回答の入力を受けつけ、答えあわせをする。

13.5.3.3 エラー処理

処理不可能な値が入力されたときの処理は、行わなくてよい。

13.5.3.4 プログラム設計条件

  1. 入出力は起動したコンソールから行う(CUIプログラムである)。
  2. 関数を作る場所は自由であるが、引数、戻り値の双方を持つ関数を一つ以上含むこと。
  3. 上記以外の部分の関数化はプログラマに一任する.
乱数を求める命令

乱数値(命令毎に毎回変わる値)を取得するには

計算機が<数>でランダム数を生成して、それを<変数名>に入れる。
					

命令を使います。

実行されるごとに異なる値が自動的に選択されます。

数-1が最大値になります。(例えば5でランダム数を生成したら、0,1,2,3,4のどれかが生成される)