コンピュータプログラミングにおいて、静的変数とは「静的に」割り当てられた変数であり、その有効期間(または「範囲」)はプログラムの実行全体にわたります。これは、スタック上で割り当てと解放が行われる、より短い有効期間の自動変数や、ヒープメモリで割り当てと解放が行われる動的に割り当てられたオブジェクトとは対照的です。
変数の有効期間はスコープ(変数が使用できる範囲)と対比されます。「グローバル」と「ローカル」はスコープを指し、有効期間を指すわけではありませんが、スコープはしばしば有効期間を暗示します。多くの言語では、グローバル変数は常に静的ですが、一部の言語では動的です。一方、ローカル変数は一般的に自動ですが、静的の場合もあります。
一般的に、静的メモリ割り当てとは、動的メモリ割り当てやとは異なり、関連するプログラムが実行される前にコンパイル時にメモリを動的メモリ割り当て自動メモリ割り当て実行時に必要に応じて割り当てられます。 [ 1 ]
静的変数は少なくともALGOL 60(1960年)まで遡り、そこでは自己変数として知られていた。
宣言には、追加の宣言子「own」を付けることができます。これにより、ブロックに再入した際に、ownで宣言された変数の値は前回の終了時の値から変更されませんが、 ownで宣言されていない変数の値は未定義となります。
— ALGOL 60に関する改訂報告書、「5. 宣言」の項、14ページ
この定義は静的変数とは微妙に異なります。動作、ひいては存続期間のみを指定し、記憶領域は指定しません。例えば、独自の変数はプログラムのロード時ではなく、関数が最初に呼び出されたときに割り当てることができます。
これらの変数を指すのに「static」という言葉が使われるようになったのは、少なくともBCPL (1966年)にまで遡り、BCPLの影響を強く受けたC言語によって普及しました。BCPLの定義は次のとおりです。
(1)静的データ項目:プログラムの実行時間と同じ期間だけ存在するデータ項目。このようなデータ項目は、明示的な定数L値を持つ。すべての静的データ項目は、関数またはルーチンの定義、グローバル宣言、またはコロンで設定されたラベルとして宣言されていなければならない。
— BCPLリファレンスマニュアル、7.2 データ項目のスペース割り当てと範囲
BCPLでは、「動的データ項目」は、現在自動変数(ローカル、スタック割り当て)と呼ばれるものに対して定義されたものであり、現在「動的割り当て」という用語が使われているヒープ割り当てオブジェクトに対して定義されたものではないことに注意してください。
キーワードstaticは、C言語や関連言語において、静的変数やその他の概念の両方に使用されます。Rustでは、キーワードを使用するか、ライフタイム注釈を使用することで、オブジェクトのライフタイムを静的にマークできます。static&'static
絶対アドレス指定モードは静的変数でのみ使用できます。なぜなら、コンパイル時にコンパイラがその位置を把握できる変数は静的変数だけだからです。プログラム(実行ファイルまたはライブラリ)がメモリにロードされる際、静的変数は(初期化されている場合は)プログラムのアドレス空間のデータセグメントに、(初期化されていない場合は) BSSセグメントに格納され、ロード前にオブジェクトファイルの対応するセクションに格納されます。
スコープと範囲に関して言えば、静的変数はプログラムの実行全体にわたって範囲を持ちますが、より限定されたスコープを持つ場合もあります。基本的な区別は、グローバルスコープを持ち、プログラム全体でコンテキストにある静的グローバル変数と、ローカルスコープを持つ静的ローカル変数です。静的ローカル変数は、それが属する関数が何回呼び出されても一度だけ初期化され、宣言された関数への多くの呼び出しを通じてその値が保持されアクセス可能であるため、ローカル変数とは異なります(たとえば、カウント変数として使用する場合など)。静的変数は、モジュールスコープ、またはC言語の内部リンケージのような、ファイルスコープまたはモジュールスコープの一種である何らかのバリアントを持つこともできます。
C言語における静的ローカル変数の例:
#include <stdio.h>void func () { static int x = 0 ; // x は func() の 5 回呼び出しの中で一度だけ初期化され、// これらの呼び出しの後、変数は 5 回インクリメントされます。 x の最終値は// 5 になります。 x ++ ; printf ( "%d \n " , x ); // x の値を出力します}int main () { func (); // 1 を出力func (); // 2 を出力func (); // 3 を出力func (); // 4 を出力func (); // 5 を出力return 0 ; }オブジェクト指向プログラミングでは、静的メンバ変数という概念もあります。これは、静的に定義されたクラスの「クラス変数」、つまり、特定のクラスのメンバ変数で、すべてのインスタンス(オブジェクト)間で共有され、これらのオブジェクトのメンバ変数としてアクセスできるものです。実行時にクラスを定義できる言語では、動的に定義されたクラスのクラス変数は、クラスが定義されたときに割り当てられ、静的ではありません。[ 2 ]
コンパイル時に既知となるオブジェクト定数(文字列リテラルなど)は、通常、静的に割り当てられます。オブジェクト指向プログラミングでは、クラスの仮想メソッドテーブルも通常、静的に割り当てられます。静的に定義された値は、スコープがグローバルであることもあり、実行全体を通して同じ不変の値が使用されることで一貫性が保たれます。
コンパイラは宣言された変数に必要なメモリ領域を割り当てます。addressof演算子を使用すると、予約されたアドレスが取得され、このアドレスをポインタ変数に割り当てることができます。宣言された変数のほとんどは静的メモリを持つため、ポインタ値をポインタ変数に割り当てるこの方法は、静的メモリ割り当てとして知られています。メモリはコンパイル時に割り当てられます。