63

extern int nnが(別のファイルで)宣言されているとコンパイルされないのに、宣言されているとstatic int n動作するのはなぜint nですか?(これらの宣言は両方ともファイルスコープにありました。)

基本的に、int nファイルスコープ内static int nが同じスコープ内と同じではないのはなぜですか?それはexternに関連しているだけですか?もしそうなら、externはどうですか?

4

4 に答える 4

138

の全体的な目的はstatic、変数がで宣言されているソースファイルに対してプライベートであることを宣言することです。したがって、外部からの接続を防ぐという役割を正確に果たしています。

ファイルスコープ変数の定義には、次の4つの種類があることに注意してください。

  1. int blah = 0;— blahはこのファイルで定義されており、他のファイルからアクセスできます。他のファイルの定義は重複しており、エラーが発生します。
  2. extern int blah;— blahは他の場所で定義する必要があり、このファイルから参照されます。
  3. int blah;—これはFORTRANと道徳的に同等ですCOMMON。これらはファイルにいくつでも含めることができ、それらはすべてリンカーによって1つの共有に解決されますint。(*)
  4. static int blah;(オプションでイニシャライザーを使用)—これは静的です。このファイルに対して完全にプライベートです。他のファイルのexternには表示されません。また、すべてが宣言されている多くの異なるファイルを持つことができstatic TYPE blah;、それらはすべて異なります。

聴衆の純粋主義者のために:'ファイル'=コンパイルユニット

(ファイルスコープではなく)静的内部関数のスコープはさらに厳密であることに注意してください。2つの関数static int bleh = 0;が同じファイル内でも宣言する場合、それらは無関係です。

(*):なじみのない人のために:通常のパターンでは、1つのコンパイルユニットがグローバル変数を定義する必要があり、他の人はそれを参照できます。それはそのコンパイルユニットに「住んでいる」。上記の(3)の場合、ファイル(またはすべてのファイル)で定義されていません。2つのファイルが言うint blah = 0;場合、リンカは複数の定義について文句を言います。2つのファイルint blah;がリンカが元気に単一のグローバルintを作成し、すべてのコードがそれを参照するようにすると言っている場合。

于 2010-05-15T21:10:34.750 に答える
7

標準Cでは、関数の外部で宣言された変数には2つのスコープがあります。変数は、それを宣言したstaticコンパイルユニット(つまり、ファイル)内でのみ表示され、非静的変数はプログラム全体で表示されます。宣言によると、変数のextern場所はまだわかっていませんが、リンカーによって分類されます。それは非静的変数と互換性がextern staticありますが、ただの狂った話です!

もちろん、実際には、最近は他の可視性があります。特に、単一のソースファイルとプログラム全体のスコープレベルがあります。単一の共有ライブラリのレベルは便利です(GCC関数属性などのメカニズムを介して設定可能)。しかし、それは非静的変数のテーマの単なるバリエーションです。static以前と同じ解釈を維持します。

于 2010-05-15T21:21:18.417 に答える
2

MSDNのドキュメントによると:

変数を変更する場合、staticキーワードは、変数に静的期間(プログラムの開始時に割り当てられ、プログラムの終了時に割り当て解除)があることを指定し、別の値が指定されていない限り、変数を0に初期化します。ファイルスコープで変数または関数を変更する場合、staticキーワードは、変数または関数に内部リンクがあることを指定します(その名前は、宣言されているファイルの外部からは表示されません)。

MSDNの静的(C ++):2015年1月にアーカイブ。最新のドキュメントも参照してください:static§ストレージクラス(C ++)| Microsoft Docs

于 2013-06-25T21:44:02.323 に答える
1

iv.c:2:1:エラー:宣言指定子の複数のストレージクラスextern static int i; ^

これが、静的変数を外部化しようとするときに得られるものです。extern staticintiを宣言します。-宣言floatintiに類似しています。floatとintを同じ宣言に含めることはできませんよね?同様に、同じ宣言にexternとstaticを含めることはできません。

于 2015-12-17T04:41:51.240 に答える