FreeBASIC マニュアルのトップに戻る

FreeBASIC ProPgInitialization

目次→教本→プログラマーのための案内Variable Initializers←オリジナル・サイト

変数の初期化子 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

変数初期化子は、事前に構築された型変数、UDT オブジェクト、配列、を初期化するためにサポートされています。

序文:
プリビルド型の変数、ユーザー定義型(UDT)オブジェクト、配列は、作成時にデフォルトでゼロ(または 'Boolean' の場合は 'False')または NULL 文字列に初期化されます。

デフォルトの変数初期化のオーバーヘッドを回避するために、'Any' 初期化子を 'Dim' と一緒に使うことで、コンパイラにメモリ内の変数の場所を確保するだけで初期化は行わないように指示することができます。
しかし、この結果、変数にはゴミが含まれることになります。この場合、プログラマーは初期値を想定してはいけません。

構築済みの型変数、UDT オブジェクト、配列は、宣言時に 'Dim ...' を使って値を与えることができます。
構築済みの型変数、UDT オブジェクト、配列は、通常の代入と同様に、'=' 記号を使って初期化されます。
固定長の文字列を宣言する場合など、宣言が式のようにならないようにするために、'=>' 記号を使うこともできます。

目次



1. プレビルド型変数宣言での初期化子構文と有効性
主なプリビルド型:
- Integer types
- Floating-point types
- Boolean types
- String types

初期化子の構文
以下に 4つの基本構文を示します。

初期化子を使った静的割当て:
(1) Dim variable_symbol [As PreBuiltType] = expression
or:
(2) Dim Byref ref_variable_symbol [As PreBuiltType] = variable

初期化子を使った動的割り当て:
(3) Dim ptr_variable_symbol As PreBuiltType Ptr = New PreBuiltType( expression )
or:
(4) Dim Byref ref_variable_symbol As PreBuiltType = *New PreBuiltType( expression )

初期化子の有効性
- expression:
'PreBuiltType' 型または互換性のある評価値を生成する必要があります。
- variable:
'As PreBuiltType' が指定されている場合は、'PreBuiltType' 変数または互換。

グローバルシンボルの宣言構文
初期化子('Dim' の代わりに 'Dim Shared''Static [Shared]''Static Var [Shared]')付きのビルド済み型変数を宣言するときに、グローバルシンボルを使う場合、初期化子引数は少なくとも、プログラムの開始時に評価され、.dataセクションに配置できるようにする必要があります:
- 'variable_symbol' はヒープ内の動的メモリブロックを参照する必要があるため、可変長文字列の初期化子構文は無効になります。
- 他のビルド済み型変数の場合、提供された引数をコンパイル時に評価できるなら、初期化子構文は有効なままです。


Dim d As Double = 1234.56789

Print d

Sleep


注意:
-lang fb だけは、'Wstring' 型の初期化値を除いて、'Dim' の代わりに 'Var' を使うことができます(明示的な型宣言を削除します)。

このページの頭に戻る



2. UDT オブジェクト宣言の初期化子構文と有効性
UDT(User Defined Type)とは、すでに存在する組み込み済みの型に加えて、ユーザーが定義した型構造のことです。

以下のすべての文(1〜7)は、UDT で明示的に定義された構築子が存在する場合、そのアクセス権を持っていることを前提としています。

初期化子の構文
7つの基本構文を以下に示します。

初期化子による静的割り当て:
(1) Dim udt_symbol As UdtName = ( argument_list )
or:
(2) Dim udt_symbol As UdtName = udt_instance
or:
(3) Dim Byref ref_udt_symbol As UdtName = udt_instance
or:
(4) Dim udt_symbol As UdtName = UdtName( argument_list )
or:
(5) Dim udt_symbol As UdtName = Type[<UdtName>]( argument_list )

初期化子を使った動的割り当て:
(6) Dim ptr_udt_symbol As UdtName Ptr = New UdtName( argument_list )
or:
(7) Dim Byref ref_udt_symbol As UdtName = *New UdtName( argument_list )

パラメータ
- argument_list:
任意の引数型のリスト(カンマで区切られた項目)。
引数が1つしかない場合、'= Type[<UdtName>]( argument )' の初期化子(有効な場合)は、 '= ( argument )' または '= argument'(変換-構築子の場合) に短縮できます。
- udt_instance:
'UdtName' のインスタンスまたは互換性(派生型)。

初期化子の有効性
- Initializer syntax line (1):
構築子が存在しない(黙示的でも明示的でもない)場合にのみ有効です。
- Initializer syntax line (2 or 3):
常に有効です。
コピー構築子(2)と参照宣言(3)の場合。
- Initializer syntax line (4):
'argument_list' に一致する黙示的か明示的な構築子が存在する場合にのみ有効です。
- Initializer syntax line (5):
構築子が存在しない場合(黙示的でも明示的でもない)、または、構築子が(黙示的または明示的)存在しても 'argument_list' に一致する場合にのみ有効です。
- Initializer syntax line (6 or 7):
この有効性は、上記の initializer syntax line (5) と同じ規則に従います。

しかし、最も複雑なのは、型構造に応じて暗黙の構築子の存在を決定するルールです:
- デフォルト構築子とデフォルト・コピー構築子を除いて、他の形式の構築子は、明示的に定義されている場合にのみ存在します。
- 暗黙のデフォルト構築子と暗黙のコピー構築子は、型の構造によって異なりますが、たとえば、(main cases) で両方とも存在します:
- 型で、黙示的 / 明示的なデフォルト構築子(メンバ文字列を含む)を持つメンバ項目を、持つか継承する。
- または、黙示的/明示的なデフォルト構築子を持つベースを持つ、型(Object から派生した型を含む)。
- .....,
- そうでない場合、例えば、初期化子を持つ変数メンバー自身は、暗黙のデフォルト構築子のみを誘導しますが、暗黙のコピー構築子は誘導しません。

記述
UDT が黙示的な構築子を持つ場合(文字列メンバ、イニシャライザ自体を持つ変数メンバ、コンストラクタを持つデータメンバ、Objectから派生した UDT、STRING*N フィールドと別のデータ型フィールドを含むfbcバージョン1.20.0以降の UDT)、または明示的な構築子を持つ場合、リスト(1)の最初のイニシャライザ構文である '= ( argument_list )'のような単純な初期化は無効になります。
その場合は、リストの最後の4つの構文(4〜7)の初期化式に一致する構築子を使うことで、高度な初期化を適用できます。

リストの最初にあるシンプルな初期化子構文(1)は、リストの最後の 4つの初期化子構文(4〜7)のうちの 1つで常に置き換えることができますが、その逆はうまくいきません。

リストの 2番目の初期化子構文(2)は、コピー構築の特殊なケースです。
この初期化子構文は、デフォルトのコピー構築でも、コピー構築子(黙示的または明示的)の方法でも、常に動作します。

リストの 3番目の初期化子構文(3)は、常に初期化子を持たなければならない参照宣言の特殊なケースです。
この初期化子構文は、'udt_instance' が参照(または逆参照されたポインタ)である場合に常に動作します。

グローバル・シンボルの宣言構文
UDT オブジェクトを初期化子付きで宣言する際にグローバルシンボルを使用する場合('Dim' の代わりに 'Dim Shared''Static [Shared]')、初期化子の引数(複数可)はプログラムの開始時に評価され、.data セクションに配置できる必要があります:
- 一覧表の(6)と(7)の初期化子構文は、シンボルがヒープ内のダイナミック・メモリ・ブロックを参照する必要があるため、有効ではなくなります。
- その他の初期化子構文は、提供された引数がコンパイル時に評価できる場合に有効です。
初期化子が既存の構築子(黙示的または明示的)を呼び出さなければならない場合、プログラムの開始時に呼び出される構築子のコードが「初期値」を .data セクションに書き込みます。

解説例
Type UDT1
    Dim As Integer I
    Dim As Integer J
End Type

Dim As UDT1 u11 = (1, 2)                  '' default-construction + initialization
'Dim As UDT1 u12 = UDT1(1, 2)             '' not valid: no Constructor(As Integer, As Integer)
Dim As UDT1 u13 = Type<UDT1>(1, 2)        '' default-construction + initialization
Dim As UDT1 Ptr pu14 = New UDT1(1, 2)     '' default-construction + initialization
    Delete pu14
Dim ByRef As UDT1 ru15 = *New UDT1(1, 2)  '' default-construction + initialization
    Delete @ru15
   
Dim As UDT1 u16 = u13                     '' default copy-construction
'Dim As UDT1 u17 = UDT1(u13)              '' not valid: no implicit Constructor(As UDT1)
Dim As UDT1 u18 = Type<UDT1>(u13)         '' default-construction + initialization
Dim As UDT1 Ptr pu19 = New UDT1(u13)      '' default-construction + initialization
    Delete pu19
Dim ByRef As UDT1 ru110 = *New UDT1(u13)  '' default-construction + initialization
    Delete @ru110
Print



Type UDT2
    Dim As Integer I = Any
    Dim As Integer J
    Declare Constructor ()
    Declare Constructor (ByVal _I As Integer, ByVal _J As Integer)
End Type
Constructor UDT2 ()
    Print "UDT2.Constructor()"
End Constructor
Constructor UDT2 (ByVal _I As Integer, ByVal _J As Integer)
    Print "UDT2.Constructor(Byval As Integer, Byval As Integer)"
    This.I = _I
    This.J = _J
End Constructor

'Dim As UDT2 u21 = (1, 2)                  '' not valid: exist constructor (due at least to '= Any' initialiser)
Dim As UDT2 u22 = UDT2(1, 2)               '' call Constructor(As Integer, As Integer)
Dim As UDT2 u23 = Type<UDT2>(1, 2)         '' call Constructor(As Integer, As Integer)
Dim As UDT2 Ptr pu24 = New UDT2(1, 2)      '' call Constructor(As Integer, As Integer)
    Delete pu24
Dim ByRef As UDT2 ru25 = *New UDT2(1, 2)   '' call Constructor(As Integer, As Integer)
    Delete @ru25
   
Dim As UDT2 u26 = u23                      '' default copy-construction
'Dim As UDT2 u27 = UDT2(u23)               '' not valid: no implicit Constructor(As UDT2)
'Dim As UDT2 u28 = Type<UDT2>(u23)         '' not valid: no implicit Constructor(As UDT2)
'Dim As UDT2 Ptr pu29 = New UDT2(u23)      '' not valid: no implicit Constructor(As UDT2)
'Dim Byref As UDT2 ru210 = *New UDT2(u23)  '' not valid: no implicit Constructor(As UDT2)
Print



Type UDT3
    Dim As Integer I
    Dim As String S
    Declare Constructor ()
    Declare Constructor (ByVal _I As Integer, ByRef _S As Const String)
End Type
Constructor UDT3 ()
    Print "UDT3.Constructor()"
End Constructor
Constructor UDT3 (ByVal _I As Integer, ByRef _S As Const String)
    Print "UDT3.Constructor(Byval As Integer, Byref As Const String)"
    This.I = _I
    This.S = _S
End Constructor

'Dim As UDT3 u31 = (1, "2")                 '' not valid: exist constructor (due at least to string member)
Dim As UDT3 u32 = UDT3(1, "2")              '' call Constructor(As Integer, As String)
Dim As UDT3 u33 = Type<UDT3>(1, "2")        '' call Constructor(As Integer, As String)
Dim As UDT3 Ptr pu34 = New UDT3(1, "2")     '' call Constructor(As Integer, As String)
    Delete pu34
Dim ByRef As UDT3 ru35 = *New UDT3(1, "2")  '' call Constructor(As Integer, As String)
    Delete @ru35
   
Dim As UDT3 u36 = u33                       '' default copy-construction
Dim As UDT3 u37 = UDT3(u33)                 '' call implicit Constructor(As UDT3)
Dim As UDT3 u38 = Type<UDT3>(u33)           '' call implicit Constructor(As UDT3)
Dim As UDT3 Ptr pu39 = New UDT3(u33)        '' call implicit Constructor(As UDT3)
    Delete pu39
Dim ByRef As UDT3 ru310 = *New UDT3(u33)    '' call implicit Constructor(As UDT3)
    Delete @ru310
Print



Type UDT4 Extends Object
    Dim As Integer I
    Dim As Integer J
    Declare Constructor ()
    Declare Constructor (ByVal _I As Integer, ByVal _J As Integer)
End Type
Constructor UDT4 ()
    Print "UDT4.Constructor()"
End Constructor
Constructor UDT4 (ByVal _I As Integer, ByVal _J As Integer)
    Print "UDT4.Constructor(Byval As Integer, Byval As Integer)"
    This.I = _I
    This.J = _J
End Constructor

'Dim As UDT4 u41 = (1, 2)                 '' not valid: exist constructor (due at least to Object as base)
Dim As UDT4 u42 = UDT4(1, 2)              '' call Constructor(As Integer, As Integer)
Dim As UDT4 u43 = Type<UDT4>(1, 2)        '' call Constructor(As Integer, As Integer)
Dim As UDT4 Ptr pu44 = New UDT4(1, 2)     '' call Constructor(As Integer, As Integer)
    Delete pu44
Dim ByRef As UDT4 ru45 = *New UDT4(1, 2)  '' call Constructor(As Integer, As Integer)
    Delete @ru45
   
Dim As UDT4 u46 = u43                     '' default copy-construction
Dim As UDT4 u47 = UDT4(u43)               '' call implicit Constructor(As UDT4)
Dim As UDT4 u48 = Type<UDT4>(u43)         '' call implicit Constructor(As UDT4)
Dim As UDT4 Ptr pu49 = New UDT4(u43)      '' call implicit Constructor(As UDT4)
    Delete pu49
Dim ByRef As UDT4 ru410 = *New UDT4(u43)  '' call implicit Constructor(As UDT4)
    Delete @ru410
Print



' Note for static UDT declaration + initializer:
'    When the initializer expression calling the constructor has only one parameter 'x', example:
'    'Dim As UDT u = UDT(x)', in this case, 'UDT(x)' can be shortened into '(x)' or even 'x', like:
'    'Dim As UDT u = (x)' or even 'Dim As UDT u = x', but all these statements call the constructor.
'    (a constructor with one parameter is called a conversion-constructor)

' The six below declarations + initialisers all call only the conversion-constructor

Type UDT5
    Dim As Integer I
    Declare Constructor ()
    Declare Constructor (ByVal _I As Integer)
End Type
Constructor UDT5 ()
    Print "UDT5.Constructor()"
End Constructor
Constructor UDT5 (ByVal _I As Integer)
    Print "UDT5.Constructor(Byval As Integer)"
    This.I = _I
End Constructor

Dim As UDT5 u51 = UDT5(1)                  '' call Constructor(As Integer)
Dim As UDT5 u52 = Type<UDT5>(1)            '' call Constructor(As Integer)
Dim As UDT5 u53 = (1)                      '' call Constructor(As Integer)
Dim As UDT5 u54 = 1                        '' call Constructor(As Integer)
Dim As UDT5 Ptr pu55 = New UDT5(1)         '' call Constructor(As Integer)
    Delete pu55
Dim ByRef As UDT5 ru56 = *New UDT5(1)      '' call Constructor(As Integer)
    Delete @ru56
   
Dim As UDT5 u57 = u54                      '' default copy-construction
'Dim As UDT5 u58 = UDT5(u54)               '' not valid: no implicit Constructor(As UDT5)
'Dim As UDT5 u59 = Type<UDT5>(u54)         '' not valid: no implicit Constructor(As UDT5)
'Dim As UDT5 Ptr pu510 = New UDT5(u54)     '' not valid: no implicit Constructor(As UDT5)
'Dim Byref As UDT5 ru511 = *New UDT5(u54)  '' not valid: no implicit Constructor(As UDT5)
Print

Sleep


注意:
-lang fb のみで、 'Dim' の代わりに 'Var' を使うことができますが(明示的な型宣言を取り除きます)、初期化値の型が曖昧であってはなりません。
前述の例では、 'Var u11 = (1, 2)' だけは動作しませんが、'Var u13 = Type<UDT1>(1, 2)' は動作します。

このページの頭に戻る



3. 配列宣言の初期化子の構文と有効性
配列は、任意の DataType を使えます。

初期化子の構文
1 つの基本的な構文を以下に示します。
(参照の配列は、現在サポートされていません)
Dim array_symbol ([lbound To] ubound) [AS DataType] = { expression [, ...] }

パラメータ
- 'lbound', 'ubound':
定数
- 'expression(s)':
コンマで区切られた項目で、波括弧で囲まれたリストを指定します。
初期化リストは 'lbound' から 'ubound' の順に並んでいます。
評価された値は 'DataType' 型または互換性のあるものでなければなりません。

初期化子の有効性
可変長(動的)配列宣言は初期化子をサポートしていないので、'lbound''ubound' は定数の数値でなければなりません。
固定長(静的)配列宣言のみが初期化子をサポートしています。

グローバル・シンボルの宣言構文
グローバル・シンボルを使って配列変数を初期化子付きで宣言する場合('Dim'の代わりに 'Dim Shared''Static [Shared]' )、初期化子の引数はプログラムの開始時に評価され、.data セクションに配置できるようにする必要があります:
- 可変長文字列の固定長(静的)配列の初期化構文は、シンボルがヒープ内の動的メモリブロックを参照しなければならないため、無効です。
- その他のプリビルド型変数の固定長(静的)配列については、提供された式がコンパイル時に評価できる場合、初期化構文は有効です。


Dim array(0 To 4) As String = {"array(0)", "array(1)", "array(2)", "array(3)", "array(4)"}

For I As Integer = 0 To 4
    Print array(I),
Next I
Print

Sleep


注意:
-lang fb でも、'Var''Dim' の代わりに使うことはできません。'Var' は配列宣言をサポートしていないからです。

このページの頭に戻る



4. 別の入れ子になった初期化子の構文
これらの変数を初期化する方法は、複雑な代入を行うために、互いに入れ子にすることができます。
たとえば、多次元配列を初期化するには、次のようにします:
Dim array(1 To 3, 1 To 5) As Integer = _
    { _
        {11, 12, 13, 14, 15}, _
        {21, 22, 23, 24, 25}, _
        {31, 32, 33, 34, 35} _
    }

For I As Integer = 1 To 3
    For J As Integer = 1 To 5
        Print array(I, J),
    Next J
    Print
Next I

Sleep


この宣言では、左端の次元の値が 5インデックスの配列として与えられています.
入れ子にすることで、任意の次元の配列を初期化することができます。

UDT と配列は、お互いに入れ子にすることができます。
例えば、次のコードは UDT の配列を宣言し、初期化しています:

Type mytype
    var1 As Double
    var2 As Integer
    var3 As ZString Ptr
End Type

Dim MyVar(0 To 1) As mytype = _
    { _
        (1.1, 1, @"Hello"), _
        (2.2, 2, @"GoodBye") _
    }

For I As Integer = 0 To 1
    Print MyVar(I).var1, MyVar(I).var2, *MyVar(I).var3
Next I

Sleep


注意:
-lang fb でも、'Var''Dim' の代わりに使うことはできません。'Var' は配列宣言をサポートしていないからです。

このページの頭に戻る


方言差: QBからの違い: 参照:
プログラマーのための案内に戻る
←リンク元に戻る プログラム開発関連に戻る
ページ歴史:2024-03-07 03:48:19
日本語翻訳:WATANABE Makoto、原文著作者:GarvanOKeeffe

ホームページのトップに戻る

表示-非営利-継承