第5講 プロシージャ(1)
第3話 2人の社員がお互いに仕事を依頼し合うとどうなる?
Module Module1
Sub Main() '私は社長だ。
Call f() 'f()君、仕事をしなさい!
End Sub
Sub f() '私は社員です。
Console.WriteLine ("こんにちは!")
Call g() 'g()君、仕事お願い!
End Sub
Sub g() '私は社員です。
Console.WriteLine ("今日は良い天気ですね。")
Call f() 'f()君、仕事お願い!
End Sub
End Module
とすると、
が続いた後、
となります。このようなときはキャンセルして下さい。
すると、
実行エラーしてしまった原因は、
このプログラムだと無限ループになってしまうからです。
私の実験によると、
仕事の依頼は4700回程度(正確には覚えていません。)が上限なのです。
その上限回数をこのプログラムだとあっという間に超えてしまします。
なぜ無限ループになってしまうのかと申しますと、
ちょうど鏡を平行に置くと無限に鏡が映し出されるのと同じ状態だからです。
f()→g()→f()→g()→f()→g()→・・・
ですね。仕事の依頼が無限に連鎖してしまいます。
無限ループは、プログラミングにおいては宿痾です。
ただし、すでにアプリやソフトと名付けたプログラムにおいては、
意図的に無限ループを利用していますし、
ゲームプログラミングは基本的に無限ループを使います。
この例外を除いては、無限ループとの戦いがプログラミングであるといっても、
決して大げさとはいえないほど、
うっかりすると無限ループの罠にはまってしまうことがあるのです。
エラーしないようにするには、
回数をカウントする変数を導入します。
プログラムソースを次のように変更して下さい。
Module Module1
Sub Main() '私は社長だ。
Call f(0) 'f()君、仕事をしなさい!
End Sub
Sub f(k As Integer) '私は社員です。
Console.WriteLine ("こんにちは!")
Call g(k) 'g()君、仕事お願い!
End Sub
Sub g(k As Integer) '私は社員です。
Console.WriteLine ("今日は良い天気ですね。")
k += 1
If k < 5 Then Call f(k) 'f()君、仕事お願い!
End Sub
End Module
(今回からわかりやすくするために改行しました。
改行や半角スペースはプログラムに何の影響を与えないのでしたね。
わかりやすく書く!が絶対原則です。)
実行画面
こんにちは!
今日は良い天気ですね。
こんにちは!
今日は良い天気ですね。
こんにちは!
今日は良い天気ですね。
こんにちは!
今日は良い天気ですね。
こんにちは!
今日は良い天気ですね。
ちょうど5回表示してプログラムが終わりました。
皆さん、
If k < 5 Then Call f(k) 'f()君、仕事お願い!
のk < 5はk <= 5ではないかと思いませんでしたか。
でもk <= 5にすると6回になってしまいます。
理由は、
Call f(0) 'f()君、仕事をしなさい!
とkが0からスタートしているからです。
0,1,2,3,4
で5つですよね。
プログラミングの世界では基本的には0からカウントするのだということを、
強く頭に刻み込んで下さい。