変数(Delphi)
データ型、変数、定数:インデックス への移動
変数は、実行時に値を変更できる識別子です。 言い換えると、変数はメモリにおける位置を示す名前であり、この名前を使用して、そのメモリの位置を読み書きすることができます。 変数はデータの容器のようなものであり、型が付けられているからこそ、コンパイラは格納されているデータをどのように解析するべきか知ることができます。
変数の宣言
変数制限の基本的な構文は次のとおりです:
var identifierList:type;
ここでの identifierList はカンマ区切りの有効な識別子のリストで、type は任意の有効な型です。 例:
var I: Integer;
これは、変数 I を型 Integer で宣言しており、
var X, Y: Real;
は、2 つの変数 X と Y を型 Real で宣言しています。
変数を連続して宣言する場合、予約語 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;
ローカル変数は、宣言内では初期化できません。 Multiple variable declarations (such as var X, Y, Z: Real;) cannot include initializations, nor can declarations of variant and file-type variables.
明示的にグローバル変数を初期化しなかった場合、コンパイラはそれを 0 で初期化します。 オブジェクト インスタンス データ(フィールド)もまた、0 に初期化されます。 ローカル変数の内容は、変数に何か代入されるまで定義されません。
変数の宣言すると、メモリが割り当てられ、これはその変数が使用されなくなると、自動的に解放されます。 特にローカル変数は、それらが宣言されている関数や手続きからプログラムが抜けるまでのみ存在します。 変数やメモリ管理の詳細については、「メモリ管理」を参照してください。
絶対アドレス
ほかの変数と同じアドレスを持つ新しい変数を作成することができます。 それを行うには、新しい変数の宣言で、型名に続けて指令 absolute を指定し、その後ろに既存の(以前に宣言した)変数の名前を指定します。 例:
var
Str: string[32];
StrLen: Byte absolute Str;
これは、変数 StrLen が Str と同じアドレスから始まることを指定しています。 短い文字列の最初のバイトには文字列の長さが格納されるため、StrLen の値は Str の長さになります。
absolute 宣言で変数を初期化したり、absolute を他の指令を組み合わせることはできません。
動的変数
動的変数は、手続き GetMem または New を呼び出すことで作成できます。 そのような変数は、ヒープ上に領域確保され、自動的には管理されません。 一度作成したら、最終的に変数のメモリを解放するにはあなたの責任です。GetMem で作成された変数を破壊する場合には FreeMem を、New で作成された変数を破壊する場合には Dispose を使用します。 動的変数を操作する他の標準ルーチンには次のものがあります: ReallocMem、AllocMem、Initialize、Finalize、StrAlloc、StrDispose。
ロング文字列、ワイド文字列、動的配列、バリアント、インターフェイスもまた、ヒープに割り当てられる動的変数ですが、それらのメモリは自動的に管理されます。
スレッドローカル変数
スレッドローカル(またはスレッド)変数は、マルチスレッド アプリケーションで使用されます。 スレッドローカル変数はグローバル変数のようですが、実行の各スレッドがそれぞれ変数のプライベート コピーを取得し、それらは他のスレッドからアクセスできない点が異なります。 スレッドローカル変数は、threadvar で宣言されます(var ではありません)。 例:
threadvar X: Integer;
スレッド変数宣言:
- 手続きまたは関数内で発生しません。
- 初期化を含めることはできません。
- absolute 指令は指定できません。
通常コンパイラによって管理される動的変数(ロング文字列、ワイド文字列、動的配列、バリアント、インターフェイス)は、threadvar で宣言できますが、コンパイラは、実行の各スレッドによって作成されたヒープ割り当てメモリを自動的に解放しません。 スレッド変数でこれらのデータ型を使用する場合には、スレッドが終了する前に、スレッド内でそれらのメモリを破棄するにはユーザーの責任です。 例:
threadvar S: AnsiString;
S := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
...
S := ''; // free the memory used by S
メモ: このような構成の使用はおすすめしません。
バリアントを Unassigned に設定することで解放し、インターフェイスまたは動的配列は nil に設定することで解放します。