変数(Delphi)
データ型、変数、定数:インデックス への移動
変数は、実行時に値を変更できる識別子です。言い方を変えると、変数はメモリ内の位置に付ける名前であり、この名前を使用してその位置に対する読み取りと書き込みを実行することができます。変数はデータの容器のようなものであり、格納されているデータの解釈方法をコンパイラが認識できるように型が付けられています。
変数の宣言
変数宣言の基本的な構文は次のとおりです。
var identifierList:type;
identifierList には有効な識別子のカンマ区切りリストを記述し、type には任意の有効な型を使用します。次に例を示します。
var I: Integer;
これは、Integer 型の変数 I を宣言します。
var X, Y: Real;
これは、X と Y という Real 型の 2 つの変数を宣言します。
変数を連続して宣言する場合、予約語 var を繰り返す必要はありません。
var
X, Y, Z: Double;
I, J, K: Integer;
Digit: 0..9;
Okay: Boolean;
手続きまたは関数の内部で宣言された変数はローカル変数、その他の変数はグローバル変数と呼ばれることがあります。次の構文を使用すると、グローバル変数を宣言と同時に初期化できます。
var identifier: type = constantExpression;
constantExpression には type 型の値を表す定数式を指定します。次の宣言があるとします。
var I: Integer = 7;
これは、次の宣言および文と同じです。
var I: Integer;
...
I := 7;
ローカル変数は宣言内で初期化できません。複数の変数宣言(var X, Y, Z: Real; など)には、初期化も、可変変数やファイル型変数の宣言も含めることができません。
明示的に初期化されていないグローバル変数はコンパイラによって 0 に初期化されます。オブジェクトインスタンスデータ(フィールド)も 0 に初期化されます。Wiin32 プラットフォームでは、ローカル変数の内容は、値が代入されるまで定義されません。
変数を宣言するとメモリが割り当てられます。このメモリは、変数が使用されなくなったときに自動的に解放されます。特にローカル変数は、その変数が宣言されている関数または手続きからプログラムが抜け出るまでの間しか存在しません。変数とメモリ管理の詳細は、「メモリ管理」を参照してください。
絶対アドレス
ほかの変数と同じアドレスを持つ新しい変数を作成することができます。それには、新しい変数の宣言で型名に続けて absolute 指令を記述し、その後ろに既存の(以前に宣言した)変数の名前を指定します。次に例を示します。
var
Str: string[32];
StrLen: Byte absolute Str;
これは変数 StrLen が Str と同じアドレスから始まることを指定します。短い文字列の第 1 バイトには文字列の長さが格納されるため、Str の長さが StrLen の値になります。
absolute 宣言で変数を初期化したり、または absolute をほかの指令と組み合わせたりすることはできません。
動的変数
GetMem 手続きまたは New 手続きを呼び出すと動的変数を作成できます。動的変数はヒープに割り当てられ、自動的な管理は行われません。作成した動的変数のメモリは、プログラマの責任で最終的に解放する必要があります。GetMem で作成した変数の破棄には FreeMem を使用し、New で作成した変数の破棄には Dispose を使用します。動的変数を処理するほかの標準ルーチンには、ReallocMem、AllocMem、Initialize、Finalize、StrAlloc、および StrDispose があります。
長い文字列、ワイド文字列、動的配列、バリアント、およびインターフェイスもヒープに割り当てられる動的変数ですが、これらの変数のメモリは自動的に管理されます。
スレッドローカル変数
スレッドローカル変数(スレッド変数)はマルチスレッドのアプリケーションで使用されます。スレッドローカル変数はグローバル変数に似ていますが、それぞれのスレッドが変数のプライベートなコピーを持ち、ほかのスレッドからはアクセスできない点が異なります。スレッドローカル変数は、var ではなく threadvar で宣言します。次に例を示します。
threadvar X: Integer;
スレッド変数の宣言には、以下の規則が適用されます。
- 手続きまたは関数の内部には記述できない
- 初期化を含めることができない
- absolute 指令を指定できない
通常、コンパイラによって管理される動的変数(長い文字列、ワイド文字列、動的配列、バリアント、インターフェイスなど)は、threadvar を使って宣言できます。ただし、コンパイラは、各実行スレッドによって作成されるヒープ割り当てメモリを自動的には解放しません。これらのデータ型をスレッド変数で使用する場合は、スレッドが消える前にスレッド内からのメモリを解放してください。次に例を示します。
threadvar S: AnsiString;
S := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
...
S := ''; // S によって使用されたメモリを解放します
メモ: このような構造の使用は推奨されません。
バリアントを解放するには Unassigned に設定し、インターフェイスや動的配列を解放するには nil に設定する。