35

C++入門書によると

各ローカル静的変数は、最初の実行がオブジェクトの定義を通過する前に初期化されます。関数が終了しても、ローカル統計は破棄されません。プログラムが終了すると、それらは破棄されます。

ローカル静的変数はグローバル静的変数と何か違いがありますか?それ以外に、それらが宣言されている場所、他に何が違うのですか?

void foo () {   
    static int x = 0;
    ++x;

    cout << x << endl;
}

int main (int argc, char const *argv[]) {
    foo();  // 1
    foo();  // 2
    foo();  // 3
    return 0;
}

と比べて

static int x = 0;

void foo () {   
    ++x;

    cout << x << endl;
}

int main (int argc, char const *argv[]) {
    foo();  // 1
    foo();  // 2
    foo();  // 3
    return 0;
}
4

7 に答える 7

38

違いは次のとおりです。

  • この名前は関数内でのみアクセスでき、リンクはありません。
  • 必ずしもプログラムの初期化段階ではなく、実行が最初に定義に到達したときに初期化されます。

2 番目の違いは、グローバル変数が初期化される前にアクセスできる静的初期化順序 fiascoを回避するのに役立ちます。グローバル変数を、ローカル静的変数への参照を返す関数に置き換えることで、何かがアクセスする前に初期化されることを保証できます。(ただし、何かがアクセスを完了する前に破棄されないという保証はまだありません。グローバルにアクセス可能な変数が必要だと思う場合は、細心の注意を払う必要があります。その状況で役立つリンクについては、コメントを参照してください。 )

于 2012-08-29T21:38:52.510 に答える
9

それらの範囲は異なります。グローバル スコープの静的変数はファイル内の任意の関数からアクセスできますが、関数スコープの変数はその関数内でのみアクセスできます。

于 2012-08-29T21:37:54.297 に答える
4

本当の名前は次のとおりです。

static storage duration object.

グローバル変数も「静的ストレージ期間オブジェクト」です。グローバル変数との主な違いは次のとおりです。

  • それらは最初に使用されるまで初期化されません
    。 注: 構築中の例外は、それらが初期化されていないため使用されなかったことを意味します。
    そのため、次に関数に入ったときに再試行されます。
  • それらの可視性はスコープによって制限されます
    (つまり、関数の外では見ることができません)。

それ以外は、他の「静的ストレージ期間オブジェクト」と同じです。

注: すべての「静的ストレージ期間オブジェクト」と同様に、それらは作成と逆の順序で破棄されます。

于 2012-08-29T21:38:42.190 に答える
2

主な、または最も重大な違いは、初期化の時間です。ローカル静的変数は、宣言されている関数への最初の呼び出しで初期化されます。グローバル変数は、main 関数の呼び出し前のある時点で初期化されます。グローバルな静的変数がほとんどない場合、不特定の順序で初期化されるため、問題が発生する可能性があります。これは、静的初期化の大失敗と呼ばれます。

于 2012-08-29T21:40:16.207 に答える
0

最初のコード ブロックでは、x は foo() 関数に対してローカルです。つまり、foo() で作成され、cout の後に関数の最後で破棄されます。ただし、2 番目のブロックでは x はグローバルです。つまり、x のスコープはプログラム全体です。int main の下に置きたい場合は、 cout << x << endl が可能で、出力されますが、最初のブロックでは x が宣言されていないと表示されます

于 2012-08-29T21:40:18.700 に答える