3-1 変数と定数

3-1-1 雛型コードの準備

これ以降しばらくは基本的な構文を扱いますが、Visual Studio .NET の 「Windows アプリケーション」 プロジェクトがもつ雛型のコードを土台にして説明します。説明で使用するコードの動作確認をしたいのであれば、まずは以下の手順に従ってプロジェクトを用意してください(操作方法の詳細は、第 2 章 「VB .NET アプリケーションの開発手順」 を参照)。

  1. プロジェクト名 WinApp2 として、Visual Basic の Windows アプリケーションプロジェクトを作成します(作成場所は任意。プロジェクトについての詳細は、2-1-1 「ソリューションとプロジェクト」 を参照)。

  2. 以下のように、フォームデザイナ上に 2 つのボタン( Button1button2 )を貼り付けます(フォームデザイナの使い方は、2-1-3 「フォームデザイナとコードエディタ」 および 2-1-4 「基本的なデザイナの操作とコードの追加」 を参照)(図 3-1)

    図 3-1 フォーム Form1.vb に 2 つのボタンを貼り付ける

    図 3-1 フォーム Form1.vb に 2 つのボタンを貼り付ける

  3. フォームデザイナ上の 2 つのボタン Button1button2 を、それぞれダブルクリックして、イベントハンドラを生成します。コードエディタには、以下のようなコードが生成されます(図 3-2)。

     図 3-2 2 つのイベントハンドラが生成される

    図 3-2 2 つのイベントハンドラが生成される

ここまで完成したら、念のため保存しておいてください。

このプログラムでは、プログラムの実行時にボタンがクリックされると、それぞれ対応するイベントハンドラが起動します。つまり、Button1 ボタンがクリックされたら Sub Button1_Click ~ End Sub のブロックが実行され、Button2 ボタンがクリックされると、Sub Button2_Click ~ End Sub のブロックが実行されます。

これ以降の説明では、このイベントハンドラ内部にさまざまな手続きを表すコードを書いて動作の検証をしていきます。今のところ、コードエディタに自動生成されている上記のコード全体の意味を正確に理解していなくても問題ありません。主に、イベントハンドラの内側だけに着目していきます。

3-1-2 VB .NET での変数

一般にプログラミングにおいては、データの計算や加工をおこなうために、データを格納する器(うつわ)として変数を使います。もちろん、VB .NET にも変数はあり、任意の名前の変数を宣言して利用することができます。

例えば、以下のような変数の宣言と利用が可能です。この例では、変数 X と変数 Ans が使われています(行番号は便宜的につけたもので、ソースコードの一部ではありません)。

[例] 変数 Ans と変数 X の利用

                  
1:  Dim X As Integer
2:  Dim Ans As Integer
3:  X = 2
4:  Ans = X + 3

1 行目と 2 行目は変数の宣言であり、それぞれ変数 X と変数 Ans が Integer 型(4 バイトの整数)であることを意味しています。この記述によって、名前 X と名前 Ans という 2 つの 4 バイトの領域がメモリ上に確保されることになります。つまり、変数の宣言は、

Dim 変数名 As データ型

というように宣言します。As 句の後ろには、変数がどんなデータ型であるかを記述します。VB .NET にどんなデータ型があるかは、3-1-3 「VB .NET でのデータ型」 で改めて扱います。また、Dim で始まるこのステートメント(文)にもさまざまなバリエーションがあります。詳しい記述方法は、3-1-5 「Dim 文によるさまざまな変数の宣言」 で扱います(なお、とりあえず変数名は、1 文字以上の任意の英数字を使うことができると考えておけばよいでしょう)。

3 行目と 4 行目は、データを格納する器である変数に、値を格納しているところです。「=」 演算子は、右項のデータを左項の変数に格納する作用があります。3 行目では、数値 2 が変数 X に格納されます。4 行目では、変数 X の値と数値 3 の足し算がおこなわれ、その計算結果が変数 Ans に格納されています。

基礎知識 & キーワード

改めて、変数とは?

変数とは、メモリ上に確保された作業領域です。一般に変数には名前がついており、名前でそれぞれの領域を識別します。実行時の機械語レベルでみた場合、本当にメモリに名前がついている訳ではなく、「アドレス(番地)」 とよばれる数値によって、1000 番地、1001 番地というように、メモリの各領域を識別しています。32 ビット CPU のマシンであれば、通常、32 ビットの数値でアドレスを表しています。そのようなアドレスを直接プログラマが指定してメモリ領域を操作するのはわかりづらいので、一般にプログラミング言語では、変数名を使って特定のメモリ領域を表現しています。

予約語、キーワード、ステートメント(文)

Visual Basic .NET には、任意の変数名(前述の Ans や X)のほかに、あらかじめ決められた意味をもった単語(前述の Dim、As、Integer など)があります。そのような単語を 「予約語」、または 「キーワード」 といいます。

また、1 つのまとまった文を 「ステートメント」、または単に 「文」 とよびます。前述のプログラムの 1 行目、2 行目は、それぞれ変数を宣言したステートメントであり、「Dim ステートメント」、または「Dim 文」とよばれます。As や Integer は、Dim による変数宣言の補助的な語句なので、As ステートメントとはいいませんし、Integer ステートメントともいいません。

VB .NET のドキュメントを調べるときも、Dim、As、Integer のどれもキーワード一覧(予約語一覧)に載っていますが、ステートメント一覧には、3 つのうち Dim しか記載されていません(Integer もキーワードですが、ドキュメントの一部では、キーワードではなくデータタイプと分類している場合もあります)。

なお、この 「=」 の操作で気を付ける点は、これは値の移動ではなく、コピーである点です。つまり、「 X = Y 」 と記述した場合、変数 Y の値が変数 X に移動してもとの変数 Y の値がなくなってしまうのではなく、変数 Y の値のコピーが変数 X に代入されます。

この変数宣言 4 行のサンプルコードは、前項で作成した WinApp2 プロジェクトのイベントハンドラ内に、以下のように記述することができます。行番号は、便宜的なものなので入力は不要です。みやすくするために、イベントハンドラ内は 4 桁だけ字下げをしました。できるだけ字下げ(インデント)を使って、意味的なまとまりがわかるようにして、読みやすくすることをお勧めします。

なお、5 行目では、変数 Ans の値を、小さなメッセージボックスに表示させるためのものです。括弧内の変数の値を表示します。また、各行のアポストロフィー 「'」 の後ろの説明文は 「コメント」 とよばれるもので、アポストロフィーより右側は任意の説明文をプログラム内に書くことができます。コメント部分は入力しなくても構いませんが、コメントを入力しておくと、あとからコードを振り返るときに役立ちます。

[例] Button1 ボタンをクリックすると、計算結果 5 がメッセージボックスに表示される

                  
   Private Sub Button1_Click(ByVal sender As System.Object, ...
1:     Dim Ans As Integer  '変数 Ans を Integer 型として宣言
2:     Dim X As Integer    '変数 X  を Integer 型として宣言
3:     X = 2               '変数 Xに 2 を代入
4:     Ans = X + 3         'X + 3 を計算して Ans に代入
5:     MsgBox(Ans)         'Ans 変数の値を画面に表示
   End Sub

ここでこのプロジェクトのプログラムを実行します(メニューから [デバッグ]→[開始]、または [デバッグ] → [デバッグなしで開始])。

このプログラムを実行すると、フォームデザイナで作成した 2 つのボタン( Button1button2 )をもつフォームが表示されるので、Button1 ボタンをクリックすると、前記のイベントハンドラが実行されます。このコードが実行されると、5 行目の記述によって、計算結果 「5」 がメッセージボックスに表示されます(図 3-3)。

 図 3-3 計算結果(変数Ansの値)の表示

図 3-3 計算結果(変数 Ans の値)の表示

参考

自動メンバ表示

IDE の既定の設定では、コードエディタ内で 「Dim Ans As」 まで入力すると、以下のようなドロップダウンリストが表示されます。これは 「自動メンバ表示」 とよばれる機能で、その時点での入力候補が自動的に表示され便利です(図 3-4)。

 図 3-4 自動メンバ表示

図 3-4 自動メンバ表示


この機能のオン/オフの切り替えは、メニューバーから [ツール]→[オプション] を選んで [オプション] ダイアログボックスを表示したのち、左ペインのツリーから[テキストエディタ]→[Basic]→[全般]を選択して、右ペインの[自動メンバ表示]チェックボックスでおこないます。

また、コードエディタ上の任意の箇所で、ctrl + space キーを押すと、このドロップダウンリストを強制的に表示できます。

3-1-3 VB .NET でのデータ型

すでに触れたように、変数宣言では 「As データ型」 のように、As キーワードの後ろには、その変数のデータ型がきます。前項の例では、「As Integer」 と指定したことによって、4 バイトの整数である Integer 型のデータ領域が変数として確保されました。ここでは、改めて Visual Basic .NET にはどのようなデータ型が用意されているか説明します。

Visual Basic .NET には、.NET Framework の CTS(Common Type System)に基づいた、以下のデータ型が用意されています(表 3-1)。

型 (タイプ)分類内容備考
Byte数値整数符号なし 1 バイト0 ~ 255
Short符号あり 2 バイト-32768 ~ 32767
Integer符号あり 4 バイト-231 ~ 231-1
Long符号あり 8 バイト-263 ~ 263-1
Single浮動小数点IEEE754 準拠 4 バイト±1.5-45 ~ ±3.438
DoubleIEEE754 準拠 8 バイト±5.0-324 ~ ±1.7308
Decimal10 進数データ型±1.0-28 ~ ±7.928
Char文字Unicode文字(1 文字、2 バイト)常に 1 文字
StringUnicode 文字列0 文字以上の可変長
Booleanその他論理型値は True か False
Date8 バイト長の日付/時間データ西暦 1 年 ~ 9999 年
Object汎用データ型 

表 3-1 データ型一覧

変数をどのようなデータとして扱いたいかによって、変数宣言における As キーワードの後ろに、これらのデータ型のどれかがきます(ただし、これらのデータ型以外にも、.NET Framework クラスライブラリには多数の型が用意されており、VB .NET で利用することができます。上記のデータ型はあくまで、VB .NET での予約語として用意されているものです)。

これらのデータ型の主な特徴について、説明しておきます。

  • 整数

    バイト長が異なる4種類の整数型が用意されています。1 ビットが整数の 1 を表すため、小数を表現することはできませんが、一般に小数を含むデータ型よりも、これら整数型のほうが計算処理を速くおこなうことができます。小数を扱う必要がない計算では、整数型の変数を使うのが適当です。

  • 浮動小数点

    小数点をともなう計算では、浮動小数点、または Decimal(次項で説明)を使うことになります。VB .NET の浮動小数点は、IEEE754 準拠の浮動小数点であり、一般的なプログラミング言語で利用されています。

    IEEE の浮動小数点では、±1.m×2n または ±0.m×2n と表記できる値について、符号、仮数(m の部分)、指数(n の部分)をビットの並びとして記憶します。IEEEに限らず、一般的に浮動小数点の小数部分の扱いでは、特に 10 進数表記とは異なるので注意が必要です。

    10 進数では、小数点第 1 位が 10 分の 1、第 2 位が 100 分の 1 となりますが、浮動小数点の仮数(m の部分)は、あるビットが 2 分の 1、その下位のビットが 4 分の 1、さらに下位が 8 分の 1 となります。そのため、10 進数の小数が浮動小数点で正確に表されるとは限りません。この誤差を浮動小数点の「まるめ誤差」といいます(IEEE 浮動小数点の正確なビット表現は、値の範囲によって多少変化します。また、「正の無限大」 や 「負の無限大」、「数でない値」 などが定義されています。正確なビット表現は、関連ドキュメントを参照してください)。

    さらに浮動小数点では、表 3-1 の Single なら有効数字が 7 桁、Double なら有効数字は 15 桁 ~ 16 桁程度と、有効桁数が限られています。そのため、財務計算などの桁数の多い計算にはむきません。桁数の大きい金額の計算には、次に説明する Decimal を使います。

  • Decimal

    Decimal は、金額が大きい財務計算にむいたデータ型です。有効数字は、28 桁 ~ 29 桁です。

    また、小数点も扱うことができます。Decimal は、±m×10n で表すデータをビットとして記憶しています。m は、0~296-1 の範囲の整数、n は -28~0 の範囲です。指数(n の部分)がマイナスになるので、小数点も表すことができます。

    ただし、浮動小数点と違い、指数の対象となる数(底)は、2 ではなく 10 です。また、仮数にあたる部分(m の部分)は、小数ではなく整数です。つまり、浮動小数点のように、小数部分が 2 分の 1、4 分の 1、8 分の 1 という値の組み合わせではなく、10 進数を想定した表現になっています。そのため、浮動小数点で起こる 「まるめ誤差」 は、Decimal には発生しません。

  • 文字の扱い

    Char 型は、1 文字データを扱うデータ型です。このデータは Unicode 文字であり、みた目が全角・半角に限らず、常に 2 バイト長です。このデータを表記するときは、"A"C のようにダブルコーテーションで囲った文字の後ろに、C を加えます。

    String 型は、可変長の文字列を扱うときのデータ型で、これも Unicode 文字列です。このデータを表記するときは、単純にダブルコーテーション(" ")を使います。

    この文字列データも .NET Framework の Common Type System に準拠したものですが、.NET Framework では、実行時の文字列操作は Unicode として扱います。ただし、プログラムのソースコードは、その OS のネイティブな文字セットを使うことができます(日本語 Windows 環境では、ShiftJIS)。例えば、以下のようなプログラムも、日本語 Windows 環境では、既定では ShiftJIS の文字セットとして保存されます。このソースプログラムを VB .NET コンパイラでコンパイルすると、文字列 「"Hello,world!"」 は、Unicode 文字列に変換されます。また、メモ帳などで Unicode としてソースプログラムを保存し、それをコンパイルすることもできます。

[例] 文字列を表す変数

                  
Dim S As String
S = "Hello,world"
  • 真偽値
    Boolean 型のデータを使うと、真(True)か偽(False)のどちらかの値を表現することができます。
  • 日付・時間
    日付、時間を表現するには、Date 型を使います。このデータも IEEE 準拠であり、64 ビット(8 バイト)を使って表現します。日付の範囲としては、西暦 1 年 1 月 1 日から 9999 年 12 月 31 日までを表現でき、あわせて、00:00:00 ~ 23:59:59 までの時間も表現することができます。
ワンポイント

● for VB6

Visual Basic .NET のデータ型は、.NET Framework に基づくので、整数型以外にも、Visual Basic 6.0 といくつか異なる点があります。VB6 にあった Variant 型は、VB .NET にはありません。その代替が、Object 型にあたります。通貨の扱いについては、VB6 の Currency 型にあたるのが、Decimal 型になります。また、以下のような VB6 の固定長文字列については、VB .NET ではサポートしません。

[例] VB6 における固定長文字列

                        
Dim S As String * 128

3-1-4 VB .NET でのリテラル表記

変数は、任意の値を代入でき、文字通り値が変化するデータですが、それ以外に、計算式では数値などの固定的なデータが直接コードに登場します。このようなデータを 「リテラル」 といいます。以下の例では、数字の 2 や文字列 "abc" はリテラルです。リテラルも、それ自身のデータ型によって表記が異なります。ここでは、データ型に応じたリテラルの表記方法を説明します。

[例] 変数 X に 2 を代入し、変数 S に "abc" を代入

                  
Dim X As Integer
Dim S As String
X = 2
S = "abc"

VB .NET はリテラルのデータ型に応じて、以下のような表記をします(表 3-2)。

型 (タイプ)使用方法
特徴明示的な記述方法
Byte通常の 10 進数整数表記が可能
先頭に &H をつけて 16 進数表記
先頭に &O をつけて 8 進数表記
Short末尾に S1000S
Integer末尾に I か %30000I 30000%
Long末尾に L か &50000L 50000&
Single明示的に小数点をつけて表記末尾に F か !50.3F 107.5!
3.14E+50F
Double末尾に R か #317.5R 385.2#
3.15E-21R
Decimal末尾に D か @115.71D 2980@
Char必ず二重引用符で囲む
(そのまま書くと変数名になってしまう)
末尾には CAC
StringABC
Boolean真偽を表す二種類の値のみTrue Flase
Date必ず # で囲む#01/22/2001#

表 3-2 リテラル表記

整数値のリテラルでは、語尾に前表にあるような接尾辞をつけることで、特定のデータ型を表すことができます。もし接尾辞を何もつけないときは、Integer 型(4 バイト)で収まるデータであれば Integer 型、それ以上であれば Long 型のリテラルとして、コンパイラは解釈します。

また、整数型において、単に数字を表記した場合は、10進数表記とみなされますが、&H をつけると 16 進数表記とみなされます。&O(英字の O、ゼロではない)をつけると 8 進数表記とみなされます。ただし、これらの表記はあくまでソースコード上の表記であり、コンパイラによって生成された内部表現は 1 と 0 のビット表現なので、どの表記をしても実質的なデータフォーマットが変わる訳ではありません。つまり、&H1F、&O37、31の 3 通りの表記は、コンパイルされたあとは、どれも数値 31 を意味する同じデータ(00011111)になります。

浮動小数点の場合、接尾辞 F や R をつけないとき、デフォルトでは Double 型とみなされます。また、浮動小数点では、そのまま数値を小数点付きで表すほかに、m×10 の n 乗という意味を、「mE±n」 と表記できます。例えば、前表にある 「3.14E+50」 は、3.14×1050 という意味です。

文字データをリテラルとして表すときは、二重引用符(ダブルコーテーション)で囲みます。もし囲まないと、文字列データではなく、変数名になってしまいます。もしくは、VB .NETの予約語として解釈されてしまうでしょう。"Dim" は String 型の文字列データですが、Dim は VB .NET の予約語です。

真偽値のリテラルは、True か False というように、そのまま記述します。もし、二重引用符で囲み、"True" としてしまったら、それは真という値ではなく、「True」 という String 型の文字列データになってしまいます。True という記述も、VB .NET にとっては、真という特別な意味をもつ予約語です。

日付や時刻をリテラルとして表現するときは、シャープ(#)で囲みます。もし、#03/23/2001# とせず、単に 03/23/2001 と表記したら、これは単なる計算式になり、コンパイラは、03÷23÷2001 という割り算として解釈します。

参考

その他の型の識別

リテラルにつけられた接尾辞のうち、「%」、「&」、「!」、「#」、「@」はリテラルだけでなく、変数につけることもできます。この接尾辞をつけることで、その変数がどんなデータ型かを表すことができます。例えば、以下の 2 つの変数宣言は、どちらの変数(D1 と D2)も Double 型であることを示しています。

[例] Double 型の変数 D1 と D2 の宣言

                        
Dim D1 As Double
Dim D2#

これ以外にも 「$」 という接尾辞があり、「Dim A$」 で文字列型として宣言できます。

この接尾辞を使った型の識別表現は VB .NET でも採用していますが、もともとこの表記方法は、Visual Basic 以前の、まだ GUI 環境がなかったころの Basic 言語にその起源があります。そのころの Basic では変数宣言文はなく、D2# と表記することで、その変数が Double 型であることを表していました。

3-1-5 Dim 文によるさまざまな変数の宣言

ここでは Dim ステートメントを使った変数宣言のバリエーションを説明します。

以下の変数宣言はどれも正しい表現です(行番号は便宜的につけたもので、実際はありません)。

[例] さまざまな Dim ステートメント

                  
1: Dim A1 As Integer = 100
2: Dim B1 As Integer, B2 As Integer = 200
3: Dim C1 As Integer = 100, C2 As String = "ABC"
4: Dim D1 = 100, D2 = "Hello"
5: Dim E1, E2, E3 As String
6: Dim F1 = 100, F2 , F3 As String
7: Dim G1, G2, G3 As String = "ABC" '×コンパイルエラー
8: Dim Ob

まず全体的な特徴としていえることは、変数宣言の際に、初期値を設定することができる点です。また、1 つの Dim ステートメントに、カンマで区切って複数の変数を宣言できることがわかります。一般形としては、以下のようになります。

Dim 変数名 As データ型 = 初期値, 変数名 As データ型 = 初期値, ...

このうち、「As 型」 や 「= 初期値」 を省略することができます。

4 行目では、As 句がありませんが、初期値の代入によってデータ型は確定できます。D1 は Integer 型になり、D2 は String 型になります。

5 行目では、変数 E1、E2、E3 の最後にだけ 「As String」 がついています。この場合、E1、E2、E3 のどれもが String 型になります。

ただし、6 行目のように 3 つの変数のうち、特定の変数に初期値を設定した場合、優先的に初期値のデータ型が採用されます。つまり、F2、F3 は String 型ですが、F1 は Integer 型です。

7 行目の場合はどうなるでしょう。やはり、G1、G2、G3 のすべての変数に "abc" が初期値として代入されるかどうかあいまいなこともあり、構文的にもエラーとして扱われ、コンパイルに失敗します。

また 8 行目では、As 句も初期値も省略しました。この場合は 「As Object」 と解釈され、Object 型として定義したものとみなされます。

参考

Option Strict

Visual Basic .NET には、ステートメントの一部を省略することで、暗黙的に定義をする機能がいくつかあります。しかし、省略による暗黙的な機能を利用すると、そのコードを書いた人が単に書き忘れたのか、それとも意図的に暗黙的機能を使おうとして省略したのか、わからないところもあり、可読性の低下や不必要なバグを招く可能性があります。

Visual Basic .NET では、Option Strict というオプションを有効にすると、そのような暗黙的な記述やいくつかのあいまいな記述をコンパイルエラーとして扱い、明示的な記述を要求することができるようになっています。

この Option Strict を有効にするには、ソリューションエクスプローラでプロジェクトを右クリックしてショートカットメニューから[プロパティ]を選び、プロジェクトの[プロパティページ]ダイアログボックスを開きます。

このダイアログボックスの左ペインのツリーから[共有プロパティ]→[ビルド]を選び、右ペインの[Option Strict]欄のドロップダウンリストを「On」に切り替えます(図 3-5)。

 図 3-5 Option Strict の設定

図 3-5 Option Strict の設定


この Option Strict をオンにすると、前述のサンプルのうち、4 行目の D1、D2、6 行目の F1、および 8 行目の Ob は、As 句によるデータ型の明示的定義がないとしてコンパイルエラーになります。4 行目の場合、D1 変数は暗黙的には Integer 型になりますが、もしかしたらコードを書いた本人は、D1 が Byte 型のつもりで使っているのかもしれません。そのようなあいまいさをなくすためにも、「Dim D1 As Byte = 100」 と明示したほうがよいでしょう。

さまざまな表現がありますが、Dim ステートメントに複数の変数を宣言する際、日ごろ使うのであれば、前述のコードのうち、3 行目か 5 行目あたりが妥当でしょう。また、基本的な形としては、冒頭に触れた一般形で覚えておくとよいでしょう。

基礎知識 & キーワード

変数名について

Visual Basic .NET では、変数などを含む識別名の命名規則は、Unicode 標準規格(Unicode Standard 3.0)の一部にあたる Technical Report 15 の 「Annex 7」 という項目に記載された規則に準拠しています。しかし、この規則を正確に覚えなくても、複数文字の英数字で表現できると覚えておけば問題ないでしょう。この規格の詳しい仕様は、以下のアドレスにあります。

この規格以外に、VB .NET の命名規則において固有な点としては、以下のものがあります。

  • 先頭にアンダーバーが利用できる。ただし、アンダーバーに続けて、有効な文字がこなければならない。
  • 大文字と小文字を区別しない。
  • キーワード(予約語)と同じ名前をつけることができない。ただし、角括弧[ ]で囲むと変数名として扱える。

大文字・小文字を区別しない点については、ほかの言語との連携を考えると、ABC、Abc、abc など、大文字・小文字の組み合わせを変えて、同じ変数 ABC を表記するのは避けたほうがよいでしょう。C/C++ や C# では、ABC、abc、Abc など、これらは異なる変数とみなされます。

また、角括弧を使うと、予約語と同じ名前の変数を使うことができます。Dim と表記すると予約語ですが、[Dim] と表記すると、Dim という名前の変数にできます。わざわざ積極的にこの機能を使う必要はありませんが、例えば、C# プログラムで Dim という名前の変数を定義してしまった場合(C# では、Dim は予約語ではありません)、その C# プログラムと連携するためには、変数を参照するとき [Dim] と表記する必要があります。

ワンポイント

● for VB6

VB6 で以下のように宣言すると、F2 だけが Integer 型で、F1 は既定の Variant 型になりましたが、VB .NET では前述のとおり、両方とも Integer 型になります。

Dim F1, F2 As Integer 'VB6 では、F2 だけ Integer 型

また、VB .NET において、Dim 文の変数宣言に初期値が書けるようになったことも新しい点です。

3-1-6 ローカル変数とメンバ変数

変数は、コード内のさまざまな場所で宣言できますが、その宣言場所によって役割が変わってきます。ここでは、そのような変数の役割の違いについて説明します。ここからは、WinApp2 プロジェクトのコードに追加修正をおこないますが、その前に作業の効率を上げるため、複数行のコメント化について説明します。

参考

複数行のコメント化

WinApp2 プロジェクトには 3-1-2 「VB .NET での変数」 において、イベントハンドラに以下の 5 行のコードを追加しましたが、このあとおこなう検証では、このコードは不要なので、文頭にアポストロフィーをつけてコメント化しておくことにします。このようにすれば、わざわざコード自体を削除しなくても、プログラムの実行対象から除外することができ、あとから振り返ることもできます。

[例] 複数行のコメント化

                        
Private Sub Button1_Click(ByVal sender As System.Object, ...
    'Dim Ans As Integer  '変数 Ans を Integer 型として宣言
    'Dim X As Integer    '変数 X を Integer 型として宣言
    'X = 2               '変数 X に 2 を代入
    'Ans = X + 3         'X + 3 を計算して Ans に代入
    'MsgBox(Ans)         'Ans 変数の値を画面に表示
End Sub

しかし、このような作業を 1 行ずつ手入力するのは面倒です。Visual Basic .NET の IDE には、このような複数行のコメントを 1 度におこなうコマンドが用意されています。

これをおこなうには、まずコメント化したい複数行をマウスでドラッグして選択し、メニューから、[編集]→[詳細]→[選択範囲のコメント]を選びます。これによって、前記のように範囲内の行すべてにアポストロフィーがつきます。また、逆に解除するためには、該当する行を選択したあと、[編集]→[詳細]→[選択範囲のコメント解除]を選びます。

それでは、WinApp2 プロジェクトの Form1.vb を使って、変数の宣言場所を考えてみます。宣言場所として考えられる候補は、以下の 3 通りが考えられます(一部、省略しています。また、行番号は便宜的なもので実際はありません)。イベントハンドラの位置を目安にして、以下のように入力してみてください。以前に入力した分は、コメント化するか削除してください。

以下の例のように入力すると、何ヵ所かでエラーが発生します。

[例] さまざまな変数宣言場所

                  
 1: Dim A As Integer      '×エラー
 2: Public Class Form1
 3:    Dim B As Integer  'メンバ変数
 4:
 5:    Private Sub Button1_Click( ...
 6:        Dim C As Integer  'ローカル変数
 7:        B = 10
 8:        C = 20
 9:        D = 30  '×エラー
10:    End Sub
11:
12:    Private Sub Button2_Click( ...
13:        Dim D As Integer  'ローカル変数
14:        B = 10
15:        C = 20  '×エラー
16:        D = 30
17:    End Sub
18: End Class

このコードでは、2 行目から 18 行目に Class ~ End Class という大きな Class ブロックがあります。3 行目の変数 B は、この Class ブロックに直接宣言されています。一方、変数 C(6 行目)や変数 D(13 行目)は、それぞれ Sub ~ End Sub のイベントハンドラのブロックに宣言されています。

イベントハンドラのような手続きを表すブロックを「メソッド」、または「プロシージャ」ともよび、変数 C や変数 D は、そのメソッド内(プロシージャ内)でのみ利用できる変数です。このような特定のメソッドに属し、そのメソッド内でのみ利用される変数を「ローカル変数」とよびます。

それに対して、変数 B のように直接 Class ブロックに記述して Class に属する変数を 「メンバ」、または 「メンバ変数」 とよびます。メンバ変数の詳しい使い方は、第 5 章 「クラスの定義と実装」 で扱います。このようなメンバ変数は、Class ブロックのほか、「Module」 や 「Structure」 とよばれるブロック内に直接記述することもできます。

なお、VB .NET では、1 行目の変数 A のように、メンバでもローカル変数でもない、どこにも属さない変数を記述することはできません。一般に、このような変数を 「グローバル変数」 といいますが、VB .NET ではグローバル変数を宣言することはできません。

メンバとローカル変数の主な違いは、その変数を参照できる範囲の違いです。

ローカル変数は特定のメソッド内でのみ利用できる、文字通りローカルな変数なので、変数 C と変数 D は、それぞれのイベントハンドラ内からしか参照できません。9 行目や 15 行目のようにイベントハンドラ(メソッド)をまたいで、ほかのイベントハンドラのローカル変数を参照することはできません。また、ローカル変数は、そのメソッド内からでないとアクセスできないことから、この例のようにわざわざ変数名を変えなくても問題ありません。それぞれ同じ変数名Cで宣言しても、それぞれイベントハンドラ内で固有に使うことができます。

メンバ変数 B は、Class ブロック(2 行目~18 行目)に属するので、同じ Class ブロック内にある 2 つのイベントハンドラから参照できます。7 行目、14 行目は正しい書き方です。メンバ変数は、複数のメソッドをまたいで利用できます。

メンバ変数の使い方を理解するには、オブジェクト指向に関するさまざまな知識が必要になるので、第 5 章 「クラスの定義と実装」 で改めて扱うことにし、第 3 章 「基本構文」 と第 4 章 「さまざまな制御構造」 では、しばらくローカル変数だけを使って基本的な構文を説明していきます。

基礎知識 & キーワード

◆スコープ(適用範囲)

メンバ変数やローカル変数など、その変数がどの範囲に属しているかを説明するとき、その範囲のことを 「スコープ」、または 「適用範囲」 とよびます。

前述のメンバ変数のスコープは Class ブロックであり、ローカル変数のスコープはメソッドということになります。

さらに VB .NET では、メソッド内のローカル変数よりも内側のスコープがあり、メソッド内に記述された特定のブロックのみに属する変数があります。以下の例では、4 行目の変数 A は While ~ End While というブロック内に定義されており、この While ブロックが変数 A にとってのスコープです。メソッドをスコープとするローカル変数 I(2 行目)よりも、さらに局所的な変数になります。6 行目のように、While ブロックの外からは参照できません(While ブロックの意味については、第 4 章 「さまざまな制御構造」 で扱います)。

[例] While ブロックをスコープにもつ変数 A

                        
1: Private Sub Button1_Click( ...
2:    Dim I As Integer = 0  'ローカル変数
3:    While I > 10
4:        Dim A As Integer    'While ブロックがスコープ
5:    End While
6:    A = 10  '×エラー While ブロックの外からアクセスできない
7: End Sub

◆変数の宣言位置

メンバ変数については、その変数が属するブロック内であれば、先頭に記述しても、終わりに記述しても構文的には正しい記述です。

ローカル変数やメソッド内の、さらに局所的なブロックをスコープにもつ変数は、その変数を使用する前であれば、スコープ内の任意の位置に宣言できます。ローカル変数を必ずしも、メソッド内の 1 行目から書く必要はありません。

3-1-7 2 種類のローカル変数

VB .NET のローカル変数の宣言には、Static 修飾子をつけるものとつけないものがあります。

[例] Static 修飾子をつけない変数とつける変数

                  
1: Private Sub Button1_Click( ...
2:     Dim X As Integer = 0
3:     Static Dim Y As Integer = 0  'Static Y と書いてもよい
4:     X = X + 1
5:     Y = Y + 1
6:     MsgBox(X)  '変数 X の値を表示
7:     MsgBox(Y)  '変数 Y の値を表示
8: End Sub

2 行目のローカル変数はいままで登場した変数宣言ですが、3 行目は Static 修飾子がついています。この 2 つはどちらもメソッド(イベントハンドラ)内のローカルな変数ですが、その変数の寿命が異なります。

2 行目の Static がつかない変数は、メソッド(イベントハンドラ)が呼び出されるたびに変数Xの領域が確保され、メソッドの処理が終了すると変数 X は開放されます。つまり、1 回のメソッド呼び出しがその変数の寿命であり、メソッド呼び出しのつど、変数 X の領域が 「動的に」 確保されます。

それに対して、3 行目の Static 修飾子がついたほうは、いわば 「静的な」 変数で、メソッド呼び出しの前から、プログラム起動の時点であらかじめ確保されています。メソッド呼び出しが終了しても、変数 Y は存在します。つまり、何回メソッドを呼び出しても、同じメモリ領域が継続的に使われます。

そのため、変数 X、Y の値は、メソッドがよばれるごとに違った値になります。

4 行目、5 行目では、それぞれ変数 X と変数 Y の値を、1 だけ増加させています。このイベントハンドラを呼び出すたびに、毎回 1 だけ増加させる処理をしますが、変数 X のほうはメソッド呼び出しのつど新しい領域が確保され、ゼロで初期化されるので、6 行目で表示される値は、常に 1 になります。一方、変数 Y は静的に存在し、プログラム起動時に 1 回だけゼロに初期化され、そのあとは継続的に同じメモリ領域を使います。つまり、変数 Y の値は、メソッドを呼び出すつど増加します。7 行目の表示では、毎回イベントハンドラがよばれるたびに増加します。

button1 ボタンを 3 回クリックしたときの、3 回目でのそれぞれのメッセージボックスの表示を以下に示します(図 3-6、図 3-7)。

 図 3-6 変数 X の表示:ファイル

図 3-6 変数 X の表示:ファイル

 図 3-7 変数 Y の表示:ファイル

図 3-7 変数 Y の表示:ファイル

ワンポイント

● for VB6

VB6 と VB .NET では、Dim と Static の書き方に若干の違いがあります。

VB6 では、以下の例のように 「Dim」 か 「Static」 かの書き分けをしており、Dim と Static は同等の位置付けですが、VB .NET では、Static は Dim 文についた修飾子と扱われます。そのため、「Dim」 か 「Static Dim」 のどちらかになり、あくまで変数宣言は Dim ステートメントであるといえます。ただし、VB .NET では、「Static Dim」 のときは Dim を省略してもよいことになっているので、結果的には、VB6 と同等の書き方もできます。

[例] VB6 での Dim と Static の使い分け

                        
Dim X As Integer
Static Y As Integer

[例] VB .NET での Static 修飾子

                        
Dim X As Integer
Static Dim Y As Integer
Static Z As Integer  'Dim は省略できる

また、VB .NET では VB6 のようにメソッド(プロシージャ)の先頭に Static をつけて表記することはできません。メソッドレベルでの Static 修飾子は、VB .NET ではサポートされていません。

なお、この Static 修飾子が利用できるのは、メソッド内のローカル変数とメソッド内のさらに内側のブロックに宣言されたブロックをスコープとする、局所的な変数です。メンバ変数には、Static 修飾子をつけることはできません。

Dd314343.illust(ja-jp,MSDN.10).gif

<< 前のページ  次のページ>>

目次