Nが(別のファイルで)_extern int n
_と宣言されたときに_static int n
_がコンパイルされないのに、_int n
_が宣言されたときに機能するのはなぜですか? (これらの宣言は両方ともファイルスコープにありました。)
基本的に、ファイルスコープの_int n
_が同じスコープの_static int n
_と同じではないのはなぜですか? externとの関係でのみですか?もしそうなら、私はexternについて何が欠けていますか?
static
の全体的および全体的な目的は、変数が変数が宣言されているソースファイルに対してプライベートであることを宣言することです。したがって、外部からの接続を防止するという正確な役割を果たしています。
ファイルスコープ変数の定義には4つの種類があることに注意してください。
int blah = 0;
—何とかはこのファイルで定義され、他のファイルからアクセスできます。他のファイルの定義は重複しているため、エラーが発生します。extern int blah;
— blahは他の場所で定義する必要があり、このファイルから参照されます。int blah;
—これは、FORTRAN COMMON
と同等の道徳的なものです。これらはいくつでもファイルに入れることができ、それらはすべてリンカによって1つの共有int
に解決されます。 (*)static int blah;
(オプションで初期化子を使用)—これは静的です。このファイルには完全にプライベートです。他のファイルの外部からは見えません。すべてがstatic TYPE blah;
を宣言する多くの異なるファイルを持つことができ、それらはすべてdifferentです。オーディエンスの純粋主義者向け: 'file' =compilation unit。
静的内部関数(ファイルスコープではない)はさらに厳密にスコープされていることに注意してください。2つの関数が同じファイル内でstatic int bleh = 0;
を宣言する場合、それらは無関係です。
(*):よく知らない人のために:通常のパターンでは、1つのコンパイル単位でグローバル変数を定義する必要があり、他のコンパイル単位はそれを参照できます。それはそのコンパイル単位で「生きています」。上記のケース(3)では、ファイル(またはすべてのファイル)がそれを定義していません。 2つのファイルがint blah = 0;
と言う場合、リンカーは複数の定義について不平を言います。 2つのファイルがint blah;
と言う場合、リンカは単一のグローバルint
を元気に作成し、すべてのコードがそれを参照するようにします。
標準Cには、関数の外部で宣言された変数のスコープが2つあります。 static
変数は、それを宣言したコンパイル単位(つまり、ファイル)内でのみ表示され、非静的変数はプログラム全体で表示されます。 extern
宣言は、変数の場所はまだ知られていないが、リンカーによってソートされることを示しています。非静的変数と互換性がありますが、extern static
はおかしな話です!
もちろん、実際には最近では他の可視性もあります。特に、単一のソースファイルとプログラム全体のレベルの間にスコープレベルがあります。単一の共有ライブラリのレベルは有用です(GCC関数属性などのメカニズムで設定可能)。しかし、それは非静的変数のテーマの単なるバリエーションです。 static
は、以前と同じ解釈を保持します。
MSDNドキュメントによると:
変数を変更する場合、staticキーワードは、変数に静的期間(プログラムの開始時に割り当てられ、プログラムの終了時に割り当て解除される)があることを指定し、別の値が指定されない限り0に初期化します。 ファイルスコープで変数または関数を変更する場合、staticキーワードは、変数または関数に内部リンケージがあることを指定します(その名前は、宣言されているファイルの外部からは見えません)。
http://msdn.Microsoft.com/en-us/library/s1sb61xd(v = vs.80).aspx :2013年6月
iv.c:2:1:エラー:宣言指定子の複数のストレージクラスextern static int i; ^
それが、静的変数を外部化しようとすることです。 extern static int iを宣言します。 -宣言float int iに類似しています。同じ宣言にfloatとintを含めることはできませんか?同様に、同じ宣言にexternとstaticを含めることはできません。