第5講 プロシージャ(1)
第6話 戻り値
今まで扱ってきた関数(社員)は、『命じられた仕事をするだけ』=『Subプロシージャ』で、
結果を命令者に報告しませんでしたが、
結果を報告する社員もあります。
『Functionプロシージャ』ですね。
結果を報告するを正確に表現すると、
値を返す−−−になります。
例えば、1から100までの和を調べて報告しなしと、
命じられて和5050を報告する社員が考えられます。
くどいようですが、比輸でなく正確に表現すると、
値5050を返す関数です。
この返す値を戻り値といいます。
ここでも事例を示しましょう。
Module Module1
Sub Main() '私は社長だ。
Dim x As Integer 'xは整数
x = 3
Console.WriteLine("{0:d}の2倍は{1:d}です。", x, f(x))
End Sub
Function f(x As Integer) 'xは整数
Return 2 * x
End Function
End Module
実行画面
3の2倍は6です。
どうして戻り値といい、そしてどこに返しているかと申しますと、
の図をご覧になればわかります。
戻す値だから戻り値ですし、
戻す場所は図のf(x)です。
さて、なぜ関数=Functionというのでしょうか。
コードを次のように書き換えて下さい。
Module Module1
Sub Main() '私は社長だ。
Dim x, y As Integer 'xは整数
x = 3
y = f(x)
Console.WriteLine("{0:d}の2倍は{1:d}です。", x, y)
End Sub
Function f(x As Integer) 'xは整数
Return 2 * x
End Function
End Module
実行結果はまったく同じです。
コードを書き換えた意図は、
y = f(x)
にあります。
高校の数学で学びましたよね。
これが関数ですね。
関数とは、左の入り口から値を入れると加工されて別の値となり、
出てくるものです。
私の実家は、温泉まんじゅうを製造販売していましたが、
その製造機械は原料を入れると加工して、おまんじゅうを出してくれるものでした。
つまり、入り口から原料を入れると、
出口からはおまんじゅうが出てきました。
関数とはおまんじゅう製造機械のようなものです。
値を加工して別の値を出してくれる機械が関数だとイメージすれば良いのです。
今回のコード
Module Module1
Sub Main() '私は社長だ。
Dim x, y As Integer 'xは整数
x = 3
y = f(x)
Console.WriteLine("{0:d}の2倍は{1:d}です。", x, y)
End Sub
Function f(x As Integer) 'xは整数
Return 2 * x
End Function
End Module
だと、入り口から3を入れると2倍に加工され、6となって出てきます。
その加工工場こそ
Function f(x As Integer) 'xは整数
Return 2 * x
End Function
なのです。
尚、
Module Module1
Sub Main() '私は社長だ。
Dim x, y As Integer 'xは整数
x = 3
y = f(x)
Console.WriteLine("{0:d}の2倍は{1:d}です。", x, y)
End Sub
Function f(x As Integer) 'xは整数
Return 2 * x
End Function
End Module
は、ピンクの部分を削り、青の部分のように変更して、
Module Module1
Sub Main() '私は社長だ。
Console.WriteLine("{0:d}の2倍は{1:d}です。", 3, f(3))
End Sub
Function f(x As Integer) 'xは整数
Return 2 * x
End Function
End Module
としても同じです。
Console.WriteLine("{0:d}の2倍は{1:d}です。", x, f(x))
のxは箱そのものではなく箱の中身である値3でしたね。
変数そのものか変数の参照(変数に入っている値)はちゃんと区別して下さい。
後でもう一度詳しく触れますが、引数で渡しているものは、
変数そのもの(箱そのもの)ではなくて、
あくまで、変数に入っている値(箱に入っている値)であることに注意して下さい。
箱そのものは原則として渡せません。
(原則としてという言葉に留意して下さい。
実は、C言語には箱そのものは渡せないのに、
箱を他の社員に使わせるという摩訶不思議な方法が用意をもっています。
C言語の良い点を取り入れたVBもやはり魔法のような方法を備えています。)
この世の中は関数で出来ていると言っても過言でないのです。
生物もインプットとアウトプットでできています。
単細胞生物も外界から栄養を吸収して、
不要物を排出します。
O157等の細菌の場合、その排出したものが人間にとっては毒物ですから、
問題になるわけですが、
生物の連鎖って結局は、インプットとアウトプットですね。
会社も同じです。
原材料を購入して、加工して製品として売り出す。
入り口と出口です。
資本と投入すると、
より多くの資本となって帰ってくるから営利企業が成立するわけです。
これもインプットとアウトプットです。
数学の関数という考え方は、
分析哲学の物事は関数関係で出来ているというアイデアの先取りだったわけです。
仕事の単位=細胞をC言語では関数といいます。
そして、VBではプロシージャといいます。
でも、値を返さないSubプロシージャも関数と考えても間違いではありません。
値を返さないとしても、仕事をするということ自体が、
命令に対する回答ですね。
仕事をすること自体が仕事を命じた人への見返りだと考えれば、
仕事をする塊のことを、
関数と呼んで良いことになります。
それで、プログラムを構成する単位=細胞=部品(パーツ)のことをC言語では、
関数と呼びますし、VBでもそう呼んでも間違いであるとは言い切れません。
ただ、VBにおける正式名称はプロシージャです。
Visual Studio Community 2017によるC言語入門を下敷きにして、
Visual Studio Community 2017によるVisual Basic入門講義を書いているために、
C言語風の書き方をしてきましたが、
VBの場合には、
Module Module1
Sub Main() '私は社長だ。
Console.WriteLine("{0:d}の2倍は{1:d}です。", 3, f(3))
End Sub
Function f(x As Integer) 'xは整数
f = 2 * x
End Function
End Module
という書き方も認められています。
fは社員名であると同時に戻り値fでもあるのです。
私は、この書き方の方が好きですが、
VBを足がかりとして、将来はC言語やJavaを学びたいと思っている方には、
Function f(x As Integer) 'xは整数
Return 2 * x
End Function
という書き方をおすすめします。
ただし、C言語やJavaでは基本すべて小文字で書くことになりますので、
return 2 * x
ですが。
さらに、付け加えますと、
条件によっては途中で処理を中断して値を返さなければならないときもありますので、
その際には
Return 2 * x
のような書き方の方が優れていることになります。
Function f(x As Integer) 'xは整数
・・・
・・・
If 条件式 Then Ruturn *
・・・
・・・
f = ・
End Function
において、条件式が成り立つ場合には、
ピンクの部分は実行されません。
すなわち、処理が途中で中断されるのです。
では、問題を出して第6話を終了します。
第5話の解答例
B引数を初項・交差・末項にして等差数列の和を計算。ただし、引数の各値はMain()においてキーボード上から取得。
Module Module1
Sub Main() '私は社長だ。
Dim s, k, m As Integer 's:初項 k:交差 m:末項
Console.WriteLine ("キーボードから初項,交差,末項の順に入力して下さい。")
Console.Write ("初項=")
s = Console.ReadLine()
Console.Write ("交差=")
k = Console.ReadLine()
Console.Write ("末項=")
m = Console.ReadLine()
Call f(s, k, m) 'f()君、初項がs、交差がk、末項がmの等差数列の和を求めなさい。
End Sub
Sub f(s As Integer, k As Integer, m As Integer) 's:初項 k:交差 m:末項
Dim i, w As Integer 'iはFor文の制御変数 wは和を積算する整数
w = 0 '0に初期化
For i = s To m Step k
w += i
Next
Console.WriteLine("初項{0:d},交差{1:d},末項{2:d}の等差数列の和={3:d}", s, k, m, w)
End Sub
End Module
のSubプロシージャf()を戻り値を持つタイプすなわちFunctionプロシージャに変更して、
同じ実行結果になるプログラムを考えて下さい。
ただし、コンソール画面への表示の仕事はMain()が担当するものとします。