1

静的変数は、少なくとも(スコープではなく)メモリの観点から、関数の外部に存在しますよね?しかし、常に気になることの1つは、関数を2回呼び出すとどうなるかということです。例えば:

f(){
    static char buffer[256*256];
    stuff(buffer);
}

この関数を2回呼び出すと、技術的には変数'buffer'を2回宣言するのではないでしょうか。または、すべてがコンパイルされると、静的変数(通常の変数とは対照的に)で異なる動作をしますか?

... c ++コンパイラが通常コードを(最適化を差し引いて)変換するチャートなどがあればいいのにと思うことがあるので、このような小さな質問で立派な人たちを煩わせる必要はありません。前もって感謝します!

編集:私はそれがこのように機能することを知っています、しかし私はただ理由を知りたいです。それはおそらく気が遠くなるほど単純なものです...

4

5 に答える 5

3

関数スコープ内の静的ストレージ期間オブジェクト。

これらのオブジェクトは、最初の使用時に作成されます。
次に、作成の逆の順序で破棄されます(他の静的ストレージ期間オブジェクトを使用)。

#include <iostream>

class X
{
    public:
        X(int x): m(x)      {std::cout << "X: " << m << " created\n"; }
        ~X()                {std::cout << "X: " << m << " destroyed\n";}

    private:
        int m;
};


static X    x1(1);

int test()
{
    std::cout << "Test: Start\n";
    static  X x3(3);

    std::cout << "Test: Finished\n";
    return 5;
}


int main()
{
    std::cout << "Main: Start\n";
    X   x2(2);

    test();

    X   x4(4);
    std::cout << "Main: Finished\n";
}

今すぐお試しください:(コメントを追加)。SSDO=>静的ストレージ期間オブジェクト。

g++ X.cpp
./a.out
X: 1 created    // SSDO file scope.
Main: Start
X: 2 created
Test: Start
X: 3 created    // SSDO created on first use (Notice not destroyed)
Test: Finished
Test: Start     // Notice not created here.
Test: Finished
X: 4 created
Main: Finished
X: 4 destroyed
X: 2 destroyed  // Main now really finished. after destroying local variables.
X: 3 destroyed  // Destroy SSDO in reverse order of creation. (3 - 1)
X: 1 destroyed
于 2011-03-03T22:33:48.413 に答える
3

いいえ、staticそれはあなたの機能の範囲外であることを意味します。これは、書くのと同じ効果があります。

static char buffer[256*256];

f(){
    stuff(buffer);
}

ただし、バッファーは関数のスコープ内でのみ表示され、コードはより読みやすくなります。

(注:charがプリミティブ型でない場合、私の例は適用されません。その場合、charは最初に「宣言」されたときに作成されます)。

于 2011-03-03T22:06:47.407 に答える
1

このコンテキストでstaticは、変数にアプリケーションの有効期間があることを意味します。main()関数に入る前に割り当てられ、main()戻った後に割り当てが解除されます。また、その値は関数呼び出し間で保持されます。これは、その関数の内部からのみ表示されるグローバル変数と考えてください。

于 2011-03-03T22:07:37.763 に答える
0

変数は、関数を呼び出す前後に存在します...静的です。

于 2011-03-03T22:05:25.993 に答える
0

この例はそれを説明するかもしれません:

#include <iostream>
using namespace std;

void test() {
  static int i = 123;
  if (i == 123) {
    i = 321;
  }
  cout << i << endl;
}

int main(int arg, char **argv) {
  test();
  test();
  return 0;
}

出力は次のとおりです。

321

321

したがって、「i」は、いわば最初に遭遇したときにのみ初期化されます。ただし、実際には、コンパイル時にその関数に割り当てられます。その後、変数として関数test()のスコープ内にありますが、静的であるため、これを変更すると、今後のtest()の呼び出しでも変更されます。

于 2011-03-03T22:10:01.857 に答える