31

staticCで、ファイル内の変数のスコープ制限としてキーワードを使用することについて疑問に思います。

私が見ているように、Cプログラムを構築する標準的な方法は次のとおりです。

  • 関数と変数を定義するcファイルの束があり、スコープが。で制限されている可能性がありますstatic
  • 他のcファイルが使用できるように、対応するcファイルの関数と場合によっては変数を宣言するhファイルの束があります。プライベート関数と変数はhファイルで公開されません。
  • すべてのcファイルは個別にoファイルにコンパイルされます。
  • すべてのoファイルはアプリケーションファイルにリンクされています。

staticとにかく変数がhファイルで公開されていない場合、gobalをとして宣言する2つの理由がわかります。

  • 1つは読みやすさのためです。変数が他のファイルでアクセスされていないことを、私を含む将来の読者に知らせてください。
  • 2つ目は、別のcファイルが変数を。として再宣言しないようにすることですextern。リンカは変数がとの両方externであることを嫌うと思いますstatic。(ファイルが他の誰かが所有する変数を再宣言するという考えは嫌いですがextern、それは大丈夫ですか?)

他の理由はありますか?

関数についても同じことが言えstaticます。プロトタイプがhファイルで公開されていない場合、他のファイルはとにかく関数を使用しない可能性があります。それでは、なぜそれを定義するstaticのでしょうか。同じ2つの理由がわかりますが、それ以上はわかりません。

4

6 に答える 6

31

他のリーダーへの通知について話すときは、コンパイラー自体をリーダーと見なしてください。変数が宣言されている場合、staticそれは最適化が開始される程度に影響を与える可能性があります。

static変数を再定義するexternことは不可能ですが、コンパイラーは(いつものように)自分をぶら下げるのに十分なロープを提供します。

static int foo;あるファイルとint foo;別のファイルに書き込む場合、名前とタイプが同じであるにもかかわらず、それらは異なる変数と見なされます。コンパイラは文句を言いませんが、後でコードを読み取ったりデバッグしたりしようとすると、おそらく非常に混乱します。extern int foo;2番目のケースで記述した場合、他の場所で非静的を宣言しない限り、リンクに失敗しint foo;ます。)

グローバル変数がヘッダーファイルに表示されることはめったにありませんが、表示される場合は宣言する必要がありますextern。そうでない場合、コンパイラによっては、そのヘッダーを含むすべてのソースファイルが変数の独自のコピーを宣言するリスクがあります。これにより、リンク障害(多重定義シンボル)が発生し、最悪の場合、いくつかの紛らわしいシャドウイングが発生します。

于 2010-06-04T12:20:23.863 に答える
10

staticファイルレベルで変数を宣言することにより(static関数内で異なる意味を持ちます)、他のユニットがそれにアクセスすることを禁止します。たとえば、別のユニット内で変数を使用しようとすると(で宣言extern)、リンカーはこのシンボルを見つけられません。

于 2010-06-04T12:04:37.707 に答える
9

静的関数を宣言すると、関数の呼び出しは「ニアコール」であり、理論的には「ファーコール」よりもパフォーマンスが向上します。あなたはより多くの情報のためにグーグルすることができます。これは私が簡単なグーグル検索で見つけたものです。

于 2010-06-04T13:07:58.047 に答える
2

グローバル変数が静的であると宣言されている場合、コンパイラーはそうでない場合よりも優れた最適化を行うことができます。コンパイラは、変数が他のソースファイルからアクセスできないことを認識しているため、コードの実行内容をより正確に推測でき(「この関数はこの変数を変更しません」など)、より高速なコードを生成する場合があります。異なる変換ユニット間でこの種の最適化を行うことができるコンパイラ/リンカーはほとんどありません。

于 2010-06-04T12:19:07.030 に答える
1

静的にせずにファイルacで変数fooを宣言し、静的にせずにファイルbcで変数fooを宣言すると、両方が自動的にexternになります。つまり、両方を初期化するとリンカーが文句を言い、そうでない場合は同じメモリ位置を割り当てる可能性があります。文句はありません。コードのデバッグを楽しんでください。

静的にせずにファイルacに関数foo()を記述し、静的にせずにファイルbcに関数foo()を記述した場合、リンカーは文句を言うかもしれませんが、そうでない場合、foo()へのすべての呼び出しは同じ機能。コードのデバッグを楽しんでください。

于 2014-04-01T06:58:23.940 に答える
-1

静的の私のお気に入りの使用法は、使用するオブジェクトを挿入または作成する必要がないメソッドを格納できることです。私が見ているように、プライベート静的メソッドは常に便利です。パブリック静的は、考えることにもう少し時間をかける必要があります。クレイジースコットが定義するものを避けるためにあなたがしていることのこと、あなたの自己をあまりにも多くのロープに巻き込み、誤って自分自身をぶら下げてしまうこと!

ほとんどのプロジェクトでヘルパークラスのフォルダーを保持するのが好きです。このフォルダーは主に静的メソッドで構成されており、オブジェクトを必要とせずにすばやく効率的に処理を実行できます。

于 2010-06-04T13:51:48.540 に答える