C言語において、staticの文字通りの意味は私たちを誤った方向に導きやすいですが、実際にはその作用は3つあります。
(1)まず最初に、その最初の、そして最も重要な作用を紹介します:隠蔽です。
複数のファイルを同時にコンパイルする場合、staticプレフィックスが付いていないすべてのグローバル変数と関数はグローバルな可視性を持ちます。この文を理解するために、例を挙げて説明します。ここでは2つのソースファイルを同時にコンパイルします。1つはa.c、もう1つはmain.cです。
以下はa.cの内容です:
a.cファイルのコード
void msg()
{
printf("Hello\n");
}
以下はmain.cの内容です:
main.cファイルのコード
{
extern char a; // extern variable must be declared before use
printf("%c ", a);
(void)msg();
return 0;
}
プログラムの実行結果は次の通りです:
A Hello
あなたはこう疑問に思うかもしれません:なぜa.cで定義されたグローバル変数aと関数msgがmain.cで使用できるのでしょうか?前述したように、staticプレフィックスが付いていないすべてのグローバル変数と関数はグローバルな可視性を持ち、他のソースファイルからもアクセスできます。この例では、aはグローバル変数、msgは関数であり、どちらにもstaticプレフィックスが付いていないため、他のソースファイルであるmain.cから見ることができます。
staticを付けると、他のソースファイルからは隠蔽されます。例えば、aとmsgの定義の前にstaticを付けると、main.cからはそれらを見ることができなくなります。この特性を利用すると、異なるファイルで同名の関数や同名の変数を定義でき、命名の衝突を心配する必要がありません。staticは関数と変数のプレフィックスとして使用でき、関数にとってstaticの作用は隠蔽のみに限られます。一方、変数にとってstaticにはさらに以下の2つの作用があります。
(2)staticの2つの作用は、変数の内容を永続のに保持することです。
静的データ領域に格納される変数は、プログラムが実行を開始した直後に初期化が完了し、これが唯一の初期化となります。静的記憶域に格納される変数は2種類あります:グローバル変数とstatic変数です。ただし、グローバル変数と比較すると、staticは変数の可視範囲を制御できます。結局のところ、staticはやはり隠蔽のために使われます。この使い方は一般的ではありませんが、例を挙げます。
実例
int fun(void){
static int count = 10; // 実はこの代入文は一度も実行されたことがない
return count--;
}
int count = 1;
int main(void)
{
printf("global\t\tlocal static\n");
for(; count <= 10; ++count)
printf("%d\t\t%d\n", count, fun());
return 0;
}
プログラムの実行結果は次の通りです:
global local static 1 10 2 9 3 8 4 7 5 6 6 5 7 4 8 3 9 2 10 1
(3)staticの3つ目の作用は、デフォルトで0に初期化されることです。
実はグローバル変数もこの属性を持っています。グローバル変数も静的データ領域に格納されるからです。静的データ領域では、メモリ内のすべてのバイトのデフォルト値はすべて0x00であり、ある場合にはこの特性がプログラマーの作業量を減らすことができます。例えば、疎行列を初期化する場合、すべての要素を1つずつ0に設定し、その後、0ではないいくつかの要素に値を代入します。静的に定義すれば、最初に0に設定する操作を省くことができます。もう1つの例として、文字配列を文字列として使いたいが、毎回文字配列の最後に\0を追加するのが面倒だと感じます。文字列を静的に定義すれば、この面倒さを省けます。なぜなら、そこは元々\0 。
だからです。小さな実験をして検証してみましょう。
実例
int a;
int main(void)
{
int i;
static char str[10];
printf("integer: %d; string: (begin)%s(end)", a, str);
return 0;
}
プログラムの実行結果は次の通りです:
integer: 0; string: (begin)(end)
最後に、staticの3つの作用を一言でまとめます。まず、staticの最も主要な機能は隠蔽です。次に、static変数は静的記憶域に格納されるため、永続性とデフォルト値0を備えています。
記事の出典:https://www.cnblogs.com/dc10101/archive/2007/08/22/865556.html