グローバルに宣言された変数はプログラムスコープを持つと言われます
静的キーワードでグローバルに宣言された変数は、ファイルスコープを持つと言われています。
例えば:
int x = 0; // **program scope**
static int y = 0; // **file scope**
static float z = 0.0; // **file scope**
int main()
{
int i; /* block scope */
/* .
.
.
*/
return 0;
}
これら2つの違いは何ですか?
C99では、「プログラムスコープ」と呼ばれるものはありません。あなたの例では、変数x
には、翻訳単位の終わりで終了するファイルスコープがあります。 y
と宣言されている変数z
およびstatic
もファイルスコープを持ちますが、内部リンケージがあります。
C99(6.2.2/3)オブジェクトまたは関数のファイルスコープ識別子の宣言にストレージクラス指定子staticが含まれている場合、識別子には内部リンケージがあります
また、変数x
には外部リンケージがあります。つまり、x
canという名前は、他の翻訳単位またはプログラム全体からアクセスできます。
C99(6.2.2/5)オブジェクトの識別子の宣言にファイルスコープがあり、ストレージクラス指定子がない場合、そのリンケージは外部です。
static
として宣言された変数は、他のファイルから直接アクセスできません。逆に、static
以外のものは、他のファイルでextern
として宣言されている場合、他のファイルからアクセスできます。
例:
foo.c
int foodata;
static int foodata_private;
void foo()
{
foodata = 1;
foodata_private = 2;
}
foo.h
void foo();
main.c
#include "foo.h"
#include <stdio.h>
int main()
{
extern int foodata; /* OK */
extern int foodata_private; /* error, won't compile */
foo();
printf("%d\n", foodata); /* OK */
return 0;
}
一般的に、グローバル変数は避けるべきです。ただし、実際のアプリケーションでは、これらはしばしば役立ちます。 extern int foo;
宣言を共有ヘッダーファイル(例ではfoo.h)に移動するのが一般的です。
Cプログラムは、いくつかのファイルに書き込むことができます。これらのファイルは、リンカーによって最終的な実行に結合されます。プログラム全体が1つのファイルにある場合、違いはありません。しかし、別個のファイルで関数のライブラリの使用を含む実際の複雑なソフトウェアでは、その違いは重要です。
ファイルスコープを持つ変数は、その宣言ポイントからファイルの最後までのみ表示されます。ファイルとは、ソースコードを含むプログラムファイルのことです。大きなプログラム内に複数のプログラムファイルが存在する場合があります。プログラムスコープを持つ変数は、プログラム全体のすべてのファイル(それが定義されているファイルだけでなく)、関数、およびその他のブロック内で表示されます。詳細については。これを確認してください: Cのスコープとストレージクラス 。