第7講 Subプロシージャ

第2話 プロシージャの独立性の意味
さて、今回はローカル変数のみを利用した簡単なソフトを2つ作り、
プロシージャの独立性の意味を考えてみましょう。
まず、1番目のソフトから。
Form1

ソースコード
Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     Dim a As Integer
     a = 5
     f1()
     f2()
     f3()
     Label1.Text = a.ToString
   End Sub

   Sub f1()
     Dim a As Integer
     a = 8
     Label2.Text = a.ToString
   End Sub

   Sub f2()
     Dim a As Integer
     a = 1
     Label3.Text = a.ToString
   End Sub

   Sub f3()
     Dim a As Integer
     a = 7
     Label4.Text = a.ToString
   End Sub

End Class
実行結果

プログラムは上から下へと流れます。
     Dim a As Integer
     a = 5
この2行の後、f1()が実施されるので
     Dim a As Integer
     a = 8
     Label2.Text = a.ToString
の3行が実施されます。もし、プロシージャの独立性がなければここでエラーしてしまいます。
なぜならDim a As Integer が重複して宣言されるからです。
次に、f2()が実行され
     Dim a As Integer
     a = 1
     Label3.Text = a.ToString
の3行が、さらにf3()が実行され
     Dim a As Integer
     a = 7
     Label4.Text = a.ToString
の3行の処理が行われ、最後に
     Label1.Text = a.ToString
が実施されますが、Label1の実行結果を見れば、
aの内容が、他のプロシージャによって書き換えられていないことがわかります。
つまり、同じ変数aであっても、それぞれの有効範囲はプロシージャの中のみなので、つまりローカル変数なので、
書き換えられる心配がないわけです。
したがって、プログラマーは自分の担当箇所だけの開発に専念すればよいことになります。
もし、独立性がなければ他の箇所にも気を配りながら開発しなければならなくなります。

今回のソフトは、f1、f2、f3において部品が用意され、
メインプログラムであるSub Button1_Clickにおいてそれらの部品が組み立てられています。
このように独立部品を組み立てて、全体をプログラミングすることを構造化プログラミングというのです。

構造化プログラミングは、プログラムがわかりやすいだけではありません。
各プロシージャは終了すると同時にメモリから消滅します。
ということは、プロシージャの中のローカル変数もメモリから消滅します。
プロシージャは、呼び出されれば発生し、終わると消滅するという生成消滅を繰り返します。
消滅によって、メモリの大幅な節約ができます。
尚、Sub Button1_Clickは、f1、f2、f3が消滅した後もまだ生きています。
まだ、すべての処理を終えず現在進行形だからです。
そして、最後の処理
     Label1.Text = a.ToString
が行われて全行程を終了して初めて消滅します。

グローバル変数は、プログラム実行中はメモリに常駐しますので、
グローバル変数を多用しすぎると、メモリが不足する事態にもなるのです。
もっとも、現在のパソコンのメモリは昔の何十万倍以上ありますから、
1万個グローバル変数を用意しようと、メモリはまだまだ余裕があります。
ですから、初心者の方はグローバル変数を使っても何の差し障りもないことになります。
ですが、将来大きなプログラムを組むことを考えてなるべくローカル変数にするようにした方がよいことも事実です。

2例目は、もう少し複雑なソフトを組んでみましょう。
Form1

コーティング
Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     '1から100までの整数の和
     f1()
     '2から100までの偶数の和
     f2()
     '1から100までの整数の2乗の和
     f3()
     '2から100まで偶数の2乗の和
     f4()
   End Sub

   Sub f1()
     Dim i As Integer, w As Integer
     w = 0
     For i = 1 To 100
       w = w + i
     Next
     TextBox1.Text = w.ToString
   End Sub

   Sub f2()
     Dim i As Integer, w As Integer
     w = 0
     For i = 2 To 100 Step 2
       w = w + i
     Next
     TextBox2.Text = w.ToString
   End Sub

   Sub f3()
     Dim i As Integer, w As Integer
     w = 0
     For i = 1 To 100
       w = w + i * i
     Next
     TextBox3.Text = w.ToString
   End Sub

   Sub f4()
     Dim i As Integer, w As Integer
     w = 0
     For i = 2 To 100 Step 2
       w = w + i * i
     Next
     TextBox4.Text = w.ToString
   End Sub

End Class
実行例


プロシージャの独立性のため各プロシージャごとに計4回もDim i As Integer, w As Integerを宣言しています。
したがいまして、むしろこの例だと不便なように思えます。
ですが、この例においてもプロシージャの便利さがわかります。
例えば、5人でも分業が可能になります。
Button1_Click、f1()、f2()、f3()、f4()の担当者が他の部分をまったく気にしないでプログラムの開発に専念できるからです。
また、変数名で頭を悩ませる必要がありません。
プロシージャの独立性が如何に便利であるかは次のようにコーティングを変更するとわかります。
Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     '1から100までの整数の和
     f1()
     '1から100までの整数の2乗の和
     f3()
     '2から100まで偶数の2乗の和
     f4()
   End Sub

   Sub f1()
     Dim i As Integer, w As Integer
     w = 0
     For i = 1 To 50
       w = w + i
     Next
     f2() '2から100までの偶数の和 プロシージャの独立性のため同じwが使われていても影響がない。
     For i = 51 To 100
       w = w + i
     Next
     TextBox1.Text = w.ToString
   End Sub

   Sub f2()
     Dim i As Integer, w As Integer
     w = 0
     For i = 2 To 100 Step 2
       w = w + i
     Next
     TextBox2.Text = w.ToString
   End Sub

   Sub f3()
     Dim i As Integer, w As Integer
     w = 0
     For i = 1 To 100
       w = w + i * i
     Next
     TextBox3.Text = w.ToString
   End Sub

   Sub f4()
     Dim i As Integer, w As Integer
     w = 0
     For i = 2 To 100 Step 2
       w = w + i * i
     Next
     TextBox4.Text = w.ToString
   End Sub

End Class

実行結果

では皆さん、上を参考に
   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     '1から100までの整数の和
     f1()
   End Sub
でも同様な結果が出るようにプログラミングして下さい。
もちろん、今回同様に半分までの和を前半でやり、中にf3などを挟み、
さらに和を再開させて最後まで求めるが条件です。
答えは30行下。





























Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     '1から100までの整数の和
     f1()
   End Sub

   Sub f1()
     Dim i As Integer, w As Integer
     w = 0
     For i = 1 To 50
       w = w + i
     Next
     f2() '2から100までの偶数の和 プロシージャの独立性のため同じwが使われていても影響がない。
     For i = 51 To 100
       w = w + i
     Next
     TextBox1.Text = w.ToString
   End Sub

   Sub f2()
     Dim i As Integer, w As Integer
     w = 0
     For i = 2 To 100 Step 2
       w = w + i
     Next
     f3() '1から100までの整数の2乗の和 プロシージャの独立性のため同じwが使われていても影響がない。
     For i = 50 To 100 Step 2
       w = w + i
     Next
     TextBox2.Text = w.ToString
   End Sub

   Sub f3()
     Dim i As Integer, w As Integer
     w = 0
     For i = 1 To 50
       w = w + i * i
     Next
     f4() '2から100までの偶数の2乗の和 プロシージャの独立性のため同じwが使われていても影響がない。
     For i = 51 To 100
       w = w + i * i
     Next
     TextBox3.Text = w.ToString
   End Sub

   Sub f4()
     Dim i As Integer, w As Integer
     w = 0
     For i = 2 To 100 Step 2
       w = w + i * i
     Next
     TextBox4.Text = w.ToString
   End Sub

End Class
実行結果

変数名が同じでも他のプロシージャで侵犯されたり、浸食されることがないので、そのプロシージャのみの開発に専念できるのです。

さて、課題を出して今話を閉じます。
Form1を

のように改造して、4つの合計の和が求めら得るようにしてみてください。
ただし、4つの合計の和を求める際、各TextBoxから値を取得してはならないという条件を付け加えます。
この課題を成就するには、
   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     '1から100までの整数の和
     f1(0)
   End Sub

   Sub f1(ByVal w As Integer)
     Dim i As Integer
     For i = 1 To 100
       w = w + i
     Next
     TextBox1.Text = w.ToString
     f2(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
   End Sub

   Sub f2(ByVal w As Integer)
     Dim i As Integer, w1 As Integer
     w1 = 0
     For i = 2 To 100 Step 2
       w1 = w1 + i
     Next
     TextBox2.Text = w1.ToString
     w = w + w1
     f3(w) 'プロシージャの独立性のため同じwが使われていても影響がない。
   End Sub

         ・
         ・
         ・
のように値が引き渡されるように変更しなければなりません。
引き渡す値を引数(ひきすう)と言います。

ここでの注目点は、wを改めて宣言していないことです。
引き渡された値がByVal w As Integerによって整数型であることがわかるからです。Valは値です。
f2のDim w1 As Integerについては、

もし、赤の枠の部分すなわち2から100までの偶数の和を示す必要がなければ入れる必要がなかったのですが、
今回は要求されているので入っています。
さて、皆さん省略されている部分を考えてみましょう。


第1話へ 第3話へ

006

VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座

数学研究室に戻る