web-dev-qa-db-ja.com

「グローバル」と「静的グローバル」の違い

グローバル変数のスコープはすべてのファイルにあり、staticグローバル変数 ' ■スコープは、宣言されたファイルにすぎません。なんでそうなの?

グローバル変数または静的グローバル変数はメモリのどこに保存されますか?

23
TwiggedToday

Cのstaticは2つの異なることを意味する可能性があるため、混乱が生じます。 1つは静的ストレージ期間であり、もう1つは内部リンケージです。ファイルスコープでキーワードとして使用されるstaticは、内部リンケージで使用される関数またはオブジェクトを提供します。

関数またはオブジェクトの内部リンケージは、別の「ファイル」で別の関数を宣言する場合(これは実際には「ファイル」ではなく、変換単位-TUと呼ばれます)、その宣言は別の関数:そのユニットで宣言された名前は、そのTUの「内部」であった他の変換ユニットで宣言された名前とは異なるエンティティに「リンク」します。同じことがオブジェクトにも当てはまります。

ファイルスコープ変数がstaticで宣言されているかどうかに関係なく、静的な保存期間があります。つまり、プログラム全体を通じて存続し、プログラムが終了すると終了します。静的な保存期間を持つオブジェクトのもう1つの例は、文字列リテラルです。静的な保存期間を持つオブジェクトが保存される場所は指定されていませんが、通常は初期化されているかどうかに応じて保存されます。初期化されたファイルスコープ変数は通常、「。data」というセクションに保存され、初期化されていないファイル-scope変数は通常、「。bss」というセクションに格納されます。変数が初期化されていない場合は、プログラムの開始時に変数がゼロで初期化されることに注意してください。 "。bss"セクションは通常、プログラムの起動時に実装によってゼロで初期化されます。

保管場所は指定されていないため、私は「通常」どこでも言った。たとえば、一部の実装では、文字列リテラルを読み取り専用セクションに格納できます。また、ファイルスコープポインターがあり、それを初期化しない場合、実装はそれをnullポインターに初期化しますが、これは必ずしもすべてのnullバイトを持つオブジェクトではありません:)

どちらもデータセグメントに格納されます。違いは、グローバルには外部から見えるリンカーシンボルがあり、静的グローバルにはないことです。

18
Dave

グローバル変数のスコープはすべてのファイルにありますが、静的グローバル変数のスコープはそれが宣言されているファイルにすぎません。

グローバル変数は、どのモジュールからでもアクセスできるように意図されています。これは、不適切なプラクティスと見なされ、絶対に必要な場合にのみ使用する必要があります。

ファイルスコープの静的変数(「静的グローバル」と言ったときに私が話していると思います)は、単一のコンパイルユニット(通常はファイル)のルーチンからアクセスできます。これは、スコープを制限するためです。変数を使用するコードを変更する場合、他のルーチンが影響を受ける可能性があるものを確認するためにどこを調べる必要があるかには、素敵な制限があります。また、名前の衝突が発生する可能性も低くなります。

グローバル変数を使用しているときに、別のモジュールセットが異なる目的で同じ名前のグローバル変数を使用している場合、別の名前を使用するように1つのセットを変更する必要があります。その問題は静的変数には存在しません。

7
Michael Burr

静的グローバルには他のファイルからアクセスできませんが、グローバル変数にはexternキーワードを使用してアクセスできます。

7
Sandip Patel

C標準では、それらがメモリのどこに格納されるかは指定されておらず、Cプログラマには関係ありません。変数にアクセスする機能は、コンパイラとリンカによって制御されます。

これは、このトピック領域で2つ目の質問です。 Cのような比較的高水準のプログラミング言語を使用する主な理由の1つは、これらの問題について心配する必要がないことです。

1
anon

静的およびグローバルに関するインタビューの質問をクラックすることを覚えておくべきポイント

  1. 静的変数に割り当てられるメモリは1度だけです。つまり、同じメモリで共有されるすべてのオブジェクトですが、グローバル変数に関しては、メモリはすべてのオブジェクトに割り当てられます。
  2. 静的変数とグローバル変数は、寿命とスコープが異なります。まず、人生とスコープとは何かを説明しましょう。オブジェクトの寿命は、オブジェクトがまだメモリ内にあるかどうかを決定しますが、オブジェクトのスコープは、オブジェクトが名前で変数にアクセスできるかどうかです。オブジェクトが有効ではないがスコープ内にある場合(ポインターを通じてオブジェクトを参照する動的に割り当てられたオブジェクトを除く)。
  3. グローバル変数にはグローバルスコープがあります。つまり、任意の関数から任意のファイルにアクセスできますが、静的変数にはファイルスコープがあります。他のファイルから変数にアクセスすることはできません。この手法は、変数をそのファイルのすべての関数にアクセス可能にしたいが、別のファイルの関数にはアクセスできないようにする場合に役立ちます。
1
Nagendra Reddy

JavaおよびC++でパブリックおよびプライベート宣言を使用するのと同じように、静的属性を使用してモジュール内の変数および関数宣言を非表示にします。Cソースファイルがモジュールの役割を果たします。すべてのグローバル変数または関数static属性で宣言されたはそのモジュールにプライベートです。同様に、static属性なしで宣言されたグローバル変数または関数はパブリックであり、他のモジュールからアクセスできます。 'global 'キーワード。

これらの変数は両方とも、再配置可能ファイルの.dataまたは.bssセクションに格納されます。

1
Ajay Gaur