変数のスコープ
これまで Dim というステートメントを厳密に理解することなく使ってきた。今回のプログラムでは Dim がプログラムのいろいろな場所で使われているが、場所によってDimの機能が若干異なる。 Dimの場所による機能の違いについて理解しよう。 これまでもDimの場所によって、変数の機能が少し異なることに気が付いていたと思う。たとえば、練習問題1のプログラムで、1行 Dim xを追加してみよう。以下の赤字の部分が追加したDim xである。
Public Class Form1
Private Sub Form1_Load( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles MyBase.Load
' Pictureboxの作成と初期化
Dim Picturebox1 As PictureBox
Picturebox1 = New PictureBox
Picturebox1.Dock = DockStyle.Fill 'ウインドウ全体にする
Picturebox1.BackColor = Color.White ' 白にする
Me.Controls.Add(Picturebox1) 'Form1と接続する
' Timerの作成と初期化
Dim Timer1 As Timer
Timer1 = New Timer
Timer1.Interval = 10
Timer1.Enabled = True
AddHandler Timer1.Tick, AddressOf Me.Timer1_Tick
' box1の作成と初期化
Dim box1 As MyBox
box1 = New MyBox(Picturebox1, Timer1) '作成する
box1.Location(0, 100)
box1.Speed(1, 0)
box1.Size(20, 20)
End Sub
Private Sub Timer1_Tick( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs _
)
' 1Tick毎に表示を更新
Me.Refresh()
End Sub
End Class
Public Class MyBox
Dim x ' x座標
Dim y ' y座標
Dim w ' 幅
Dim h ' 高さ
Dim vx ' 1Tickあたりのx方向移動量
Dim vy ' 1Tickあたりのy方向移動量
Public Sub New(ByVal p1 As PictureBox, ByVal t1 As Timer)
AddHandler p1.Paint, AddressOf Paint
AddHandler t1.Tick, AddressOf Tick
End Sub
Public Sub Location(ByVal x1, ByVal y1)
' 位置(x,y)を指定された値(x1,y1)にする
x = x1
y = y1
End Sub
Public Sub Size(ByVal w1, ByVal h1)
' サイズ(w,h)を指定された値(w1,h1)にする
w = w1
h = h1
End Sub
Public Sub Speed(ByVal vx1, ByVal vy1)
' 速度(vx,vy)を指定された値(vx1,vy1)にする
vx = vx1
vy = vy1
End Sub
Public Sub Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs)
' 指定された速度で移動する
Dim x
x = (x + vx + 300) Mod 300
y = (y + vy + 300) Mod 300
End Sub
Public Sub Paint(ByVal sender As Object, _
ByVal e As System.Windows.Forms.PaintEventArgs)
Dim g As Graphics
Dim pen As System.Drawing.Pen
g = e.Graphics
pen = New System.Drawing.Pen( _
Color.FromArgb(&HFFFF0000))
g.DrawRectangle(pen, x, y, w, h)
End Sub
End Class
|
すると x 方向には動かなくなってしまう。なぜだろうか。
フォームにButton1とLabel1を置いて、以下のプログラムを実行してみよう。
Public Class Form1
Dim x
Private Sub proc1()
Dim x
x = 3
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
x = 10
proc1()
Label1.Text = x
End Sub
End Class
|
このプログラムをこのまま実行すると、Label1には10が表示される。赤字のDim xを 'Dim xとしてコメントに変更してから実行すると、Label1には3が表示される。
Debugモードで変数の動きをみてみよう。
Dim xを残した場合
Sub proc1が終了するとxの値が10に戻る。
Dim x をコメントにした場合
Sub proc1が終了してもxの値は3のままだ。
Dim x と変数の関係を図に示す。
Private Sub proc1 の中に Dim xがあると、01行目と03行目では名前はxで同じだが、別々の変数が作られる。そのため、04行目でxに3が代入されても、01行目で宣言した方のxの値は変わらない。
Dim xをコメントに書き換えると以下のようになる。
このようなルールのことを、「スコープ(視界)」と言う。スコープについて、すべてのルールをあげるとかなり複雑であるが、ここでは特によく使用するスコープについて簡単にまとめておく。
定義する場所 スコープ 同一の変数として参照される範囲 同一の値を保持する範囲 クラス定義よりも外側 名前空間スコープ そのプログラム内 そのプログラム内 クラス定義の内側でサブプロシージャの外側 モジュールスコープ そのクラス内 そのクラスのインスタンス内 サブプロシージャの最初の部分 プロシージャスコープ そのプロシージャ内 そのプロシージャの実行が開始してから終了するまで Visual Studio のコードエディタを使用している場合は、スコープはだいたい同じインデントの範囲と覚えておけばよい。
最初に戻って、なぜ赤色のDim xを元の命令に戻すと、アニメーションが止まったかといえば、Dim xによって新しい変数が定義され、xに関する式ではx座標ではなく関係のない変数xを使って計算や代入が実行されたからだ。
さらに詳しく知りたい場合は、Visual StudioのHELPから以下の
「オブジェクトによるプログラミング: クラスを使用する」
を見よう。
- 開発ツールと言語ドキュメント | - Visual Studio ドキュメント | | + Visual Studioの紹介 | | + Visual Studioの統合開発環境 | | 使用する技術とツールの決定 | | + Windowsベースのアプリケーション、コンポーネント、サービス | | + Visual Studioでの.NET Framework プログラミング | | - VIsual Basic | | | + 概要 | | | - Visual Basic ガイドツアー | | | | + Visual Basic Expressの概要 | | | | + プログラムの外観の作成: Windowsフォームの概要 | | | | + 問題の確認 : デバッグを行ってエラーを検出し、修正する方法 | | | | + レコードの管理 : プログラムでデータを使用する | | | | - オブジェクトによるプログラミング : クラスを使用する