典型的な C プログラムでは、静的変数とグローバル変数の両方がデータ セグメントに存在します。それでも、静的変数のスコープはファイルに限定されています。それどころか、グローバル変数はどこからでもアクセスできます。両方が同じメモリにあるのに、なぜそれが起こるのですか?
4 に答える
意図的に。
static
at global scope は、「これらの変数のスコープを制限したい。他のモジュールが同じ名前の変数を宣言したことを気にしたくない」という意味で使用するキーワードです。このキーワードを使用する理由と使用しない理由は、実際にはまさにその存在の理由です。
キーワードは、異なるコンテキストでは異なるものを意味することに注意してください。関数スコープstatic
では、「この変数の内容は関数呼び出し間で保持される必要がある」ことを意味します。
結果として生じるメモリ内のデータの実際の配置は実装の詳細であり、コンパイラとプラットフォームによって異なります。
Why does it happen, although both resides in the same memory?
簡潔な答え:-
C11 標準 ( 6.2.2 識別子のリンク) パラ 4 から:
オブジェクトまたは関数のファイル スコープ識別子の宣言に storageclass 指定子staticが含まれている場合、識別子には内部リンケージがあります。
内部結合とは、その翻訳単位内でのみ可視であることを意味します。
詳細な回答:
グローバル変数(静的なし) には外部リンケージがあります。これは、他の翻訳単位から見えることを意味します。
ファイルスコープで静的変数を宣言すると内部リンケージがありますが、ブロックスコープで宣言するとリンケージがありません。
具体的にいくつかの用語を理解しましょう.( C キーワード (静的)から着想を得ています)
AC 変数には、次のいずれかのリンケージがあります。
- リンケージなし :-ブロック スコープを持つ変数にはリンケージがありません。つまり、変数が定義されているブロックに対してプライベートであることを意味します。自動、スレッド、および動的ストレージ期間を持つすべての変数には、このリンケージがあり、ブロック スコープで静的に宣言された変数も同様です。ファイル スコープを持つ変数は、内部リンケージまたは外部リンケージのいずれかを持つことができます。
- 内部リンケージ :-変数は、現在の翻訳単位のすべてのスコープから参照できます。ファイル スコープで宣言されたすべての変数には、このリンケージがあります。これには、ファイル スコープで静的に宣言された変数も含まれます。
- 外部リンケージ:-変数は、プログラム全体の他の翻訳単位から参照できます。明示的なストレージ クラス指定子なしで extern または const のいずれかで宣言されているが static ではないすべての変数には、このリンケージがあります。
例えば-
int i = 5; // file scope, external linkage
static int j = 3; // file scope, internal linkage
...
...
int main()
{
...
...
}
int func ()
{
static int num;// block scope – no linkage
. . .
}
ファイルレベルで変数 static を宣言することにより (static
関数内では異なる意味を持つ)、他のユニットがそれにアクセスすることを禁止します。たとえば、別のユニット内で変数を使用しようとすると (で宣言されextern
ます)、リンカはこのシンボルを見つけられません。
強調鉱山:)
技術的には、何にでもアクセスできます。コンパイラはメモリアドレスを提供しません。自分で取得する必要があります。何とかして。