ストレージ クラスとスコープは別のものです。キーワードはstatic
スコープに影響しません。
ストレージ クラスは、オブジェクトの有効期間または保存期間に関連しています。オブジェクトが作成されたときと、その有効期間が終了したときです。残念ながら、歴史的な理由により、ストレージ クラスと他の概念が混在しています。ストレージ クラスには、何かが格納される場所に関するいくつかの意味があります。C は進化して、何かを格納する場所に関する決定は主に実装に委ねられるようになりました。通常、プログラマーは、何かが格納されるタイミングだけを気にする必要があります。
ストレージ クラスはオブジェクトのプロパティです: 格納される実際のもの (値)。スコープは識別子のプロパティです。オブジェクト (または型または関数) を参照するために使用される名前です。
保存期間には、静的、スレッド、自動、割り当ての 4 つがあります。スコープには、関数、ファイル、ブロック、関数プロトタイプの 4 種類があります。それらのルールはいくぶん複雑です (また、外部、内部、またはなしのリンケージにも依存します) ので、すべてを説明することはしません。
オブジェクトを と定義するとstatic
、その存続期間はプログラムの実行全体になります。デフォルトでは、関数本体内で宣言された通常のオブジェクトには自動保存期間があります。その存続期間は、プログラムの実行がブロックに入ってから、プログラムの実行がブロックから出るまでです。実行がブロックに入るたびに、オブジェクトの新しいインスタンスが作成されます。ご覧のとおり、lifetime はプログラムの実行中に適用されるプロパティです。
関数本体内でオブジェクトを宣言すると、宣言内の識別子 (名前) はブロック スコープを持ちます。名前はブロック内でのみ表示されます。スコープはコンパイル時のプロパティです。ソースコードのどの部分が名前を見ることができるかに影響します。たとえば、関数 A が実行時に関数 B を呼び出す場合、関数 B は関数 A 内の名前を認識できません。 -time プロパティ) は関数 B では表示されません。
関数本体内の名前にはブロック スコープがありますが、自動 (ブロック) 保存期間を持つオブジェクトまたは静的 (プログラム全体) 保存期間を持つオブジェクトを参照できます。
関数本体の外側でオブジェクトを宣言する場合、その識別子にはファイル スコープがあります。ファイル内の後続のすべてのソース コードに表示されます。
リンケージという性質もあります。リンケージは、異なるスコープの同じ識別子が同じオブジェクトを参照できるようにする方法です。(foo
あるソース ファイルの は、別のソース ファイルの と同じオブジェクトを参照するように作成できfoo
ます。)