C言語において、staticの文字通りの意味は私たちを誤った方向に導きやすいですが、実際にはその作用は3つあります。

(1)まず最初に、その最初の、そして最も重要な作用を紹介します:隠蔽です。

複数のファイルを同時にコンパイルする場合、staticプレフィックスが付いていないすべてのグローバル変数と関数はグローバルな可視性を持ちます。この文を理解するために、例を挙げて説明します。ここでは2つのソースファイルを同時にコンパイルします。1つはa.c、もう1つはmain.cです。

以下はa.cの内容です:

a.cファイルのコード

char a = 'A'; // global variable
void msg()
{
    printf("Hello\n");
}

以下はmain.cの内容です:

main.cファイルのコード

int main(void)
{    
    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はやはり隠蔽のために使われます。この使い方は一般的ではありませんが、例を挙げます。

実例

#include <stdio.h>

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 。

だからです。小さな実験をして検証してみましょう。

実例

#include <stdio.h>

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