変数とオブジェクトに関する、見えることと、アクセス規則
変数の範囲は、プログラムにおける、見えることについて言及します。
変数は、変数が宣言された範囲の外では、見えません(アクセスできません)。
変数が、どこでどう宣言されたかで、変数の範囲が決定されます。
FreeBASIC では、4つの範囲の種類があります:
local(地方)、shared(共有)、common(共通)、common shared(共通共有)
これらの各範囲には、異なった見える規則があります。規則の詳細は、下記です。
地方の範囲
地方の範囲で宣言された変数は、宣言されている、IF、SELECT、WITH、FOR、WHILE、DO、SCOPE、手続き、モジュールブロックの、最もローカルなインスタンスだけで表示されます。
ローカル範囲では、モジュール・レベルのコードと、手続きレベルのコードの間に、可視性はありません。
さらに、ブロック決定やループ命令文内で定義された変数は、変数が定義されたブロック内だけで表示されます。
モジュールの、ローカル範囲で宣言された変数は、そのモジュール内のどの手続きにも、表示されません。
同様に、手続き内で宣言されたローカル変数は、モジュール・レベルのコードやモジュール内の他の手続きでは、表示されません。
Scope ブロックの中で宣言された変数は、地方の範囲で宣言されるだけで、ブロックの外で見えません。
Scope ブロックは、しかしながら、周囲の範囲を引き継ぐので、
Scope ブロックの外で宣言された局所変数は、
Scope ブロックの中で見えます。(
プログラム例を参照ください)
Dim 命令文を使って、変数を明示的にローカル範囲として宣言することができます。
また、変数を導入するだけ(
-lang qb と
-lang fblite 方言のみ)で暗黙的にローカル範囲として宣言することもできます(
暗黙の宣言 を参照)。
プログラム例
local.bas は、ローカル範囲の可視性ルールを示しています。
local.bas
'' このモジュールの中だけで、見えます。
Dim As Integer local_moduleLevel1
'' OK.
Print "local_moduleLevel1" ; local_moduleLevel1
Scope
'' OK;
SCOPE Blocks は外側の範囲を引き継ぎます。
Print "local_moduleLevel1" ; local_moduleLevel1
'' この SCOPE Block の中だけで、見えます」。
Dim As Integer local_moduleLevel2
'' OK.
Print "local_moduleLevel2" ; local_moduleLevel2
End Scope
'' エラー;
SCOPE の中の変数を見ることができません。
'' local_moduleLevel2 を表示します
Print "local_moduleLevel2" ; local_m
Function some_function( ) As Integer
'' この関数の中だけで、見えます。
Dim As Integer local_functionLevel
'' OK.
Print "local_functionLevel" ; local_functionLevel
'' エラー;
ローカル・モジュールレベルの変数を見ることができません。
'' local_moduleLevel1 を表示します
'' エラー;
ローカル・モジュールレベルの変数を見ることができません。
'' local_moduleLevel2 を表示します
Function = 0
End Function
'' local_functionLevel を表示
'' エラー;
関数レベルの変数を見ることができません。
Print "local_functionLevel" ; local_functionLevel
Sleep
End 0
共有された範囲
モジュールの、共有範囲で宣言された変数は、モジュールとそのモジュールのすべての手続きの、両方に表示されます。
ローカル範囲とは異なり、共有範囲は、モジュール・レベルの変数を、そのモジュールの手続きから見えるようにします。
つまり、モジュールは、その宣言を、その手続きと
共有します。
変数は、モジュール・レベルでのみ共有範囲であると宣言できます。
つまり、モジュールだけが、変数を共有できます。
手続きも、
Scope ブロックも、共有範囲内で変数を宣言できないので、そこで宣言された変数は、その手続やブロックに対してだけの、ローカルになります。
Shared キーワードを指定した DIM(または REDIM や STATIC)命令文を使って、変数を共有範囲で宣言できます。
プログラム例
shared_scope.bas は、共有範囲の可視性ルールを示しています。
shared.bas
'' このモジュール中で、見えます
Dim Shared As Integer shared_moduleLevel1
'' OK.
Print shared_moduleLevel1
Scope
'' OK;
範囲外の変数を見ることができます
Print shared_moduleLevel1
'' Error;
SCOPE-レベルの変数を共有できません
'' dim shared as integer shared_ModuleLevel2
End Scope
End 0
Function some_function( ) As Integer
'' OK;
共有されたモジュールレベル変数を見ることができます
Print shared_moduleLevel1
'' Error;
関数レベル変数を共有できません
'' dim shared as integer sharedFunctionLevel
Function = 0
End Function
共通の範囲
共通の範囲で宣言された変数は、すべてのモジュールで見えます。
Common と共に宣言された変数は、対応する
Common 変数宣言で、他のモジュールから見えます。
宣言された変数名は、モジュール間で合致しなければなりません。
module1.bas
'' 以下でコンパイルしてください
'' fbc -lang qb module1.bas module2.bas
'$lang:
"qb"
Declare Sub Print_Values
()
Common m1 As Integer
Common m2 As Integer
' これは他のすべてのモジュールの後に実行されます'
m1 = 1
Print "Module1"
Print "m1 = ";
m1 ' m1 = 1 このモジュールで設定されて
Print "m2 = ";
m2 ' m2 = 2 module2 で設定されて
Print_Values
module2.bas
Common m1 As Integer
Common m2 As Integer
m2 = 2
Print "Module2" ' これは最初に実行される
Print "m1 = ";
m1 ' m1 = 0
(デフォルトで)
Print "m2 = ";
m2 ' m2 = 2
Sub Print_Values
()
Print "Module2.Print_Values"
Print "m1 = ";
m1 ' Implicit variable = 0, because '-lang qb' use
Print "m2 = ";
m2 ' Implicit variable = 0, because '-lang qb' use
End Sub
出力:
Module2
m1 = 0
m2 = 2
Module1
m1 = 1
m2 = 2
Module2.Print_Values
m1 = 0
m2 = 0
共通の共有範囲
共通の共有範囲で宣言された変数は、すべてのモジュールと、そのモジュールのすべての手続きに、表示されます。
Common と共に宣言された変数は、対応する
Common 変数宣言で、他のモジュールに見えます。
宣言する変数名は、モジュール間で、合致しなければなりません。
モジュールの中で、
Shared 宣言修飾語は、変数に、モジュール範囲を与えて、変数が、すべての sub と関数で見えるようにします。
module3.bas
'' 以下でコンパイルしてください
'' fbc module3.bas module4.bas
Declare Sub Print_Values
()
Common m1 As Integer
Common m2 As Integer
'' これは他のすべてのモジュールの後に実行されます
m1 = 1
Print "Module3"
Print "m1 = ";
m1 '' m1 = 1 このモジュールで設定されて
Print "m2 = ";
m2 '' m2 = 2 module2 で設定されて
Print_Values
module4.bas
Common Shared m1 As Integer
Common Shared m2 As Integer
m2 = 2
Print "Module4" '' これは最初に、実行されます
Print "m1 = ";
m1 '' m1 = 0
(デフォルトで)
Print "m2 = ";
m2 '' m2 = 2
Sub Print_Values
()
Print "Module4.Print_Values"
Print "m1 = ";
m1 '' m1 = 1
Print "m2 = ";
m2 '' m2 = 2
End Sub
出力:
Module4
m1 = 0
m2 = 2
Module3
m1 = 1
m2 = 2
Module4.Print_Values
m1 = 1
m2 = 2
例:
上の例を見てください。
参照: