9

次の C++ コードでは:

    for (int i=0; i<10; i++)
    {
        int y = someFunctionCall();

        //Some statements
    }

変数 (y) は、ループが反復されるたびに割り当てられ、反復が完了すると割り当てが解除されますか、またはすべてのループ反復に対して 1 回割り当てられますか?

上記のコードは以下と同等ですか?:

    int y;
    for (int i=0;i<10;i++)
    {
        y = someFunctionCall();

        //Some statements
    }
4

7 に答える 7

6

関数が呼び出されると、一度スタックに割り当てられます。パフォーマンスに関しては、2 つの方法に違いはありません (ただし、最後の方法でyは、ループ後もスコープ内にあることを思い出してください)。変数が各反復間で作成および破棄されるように見える (反復間でその値を「失う」ようにする) ことは、コンパイラによって作成される動作です。実際のメモリ位置は常に同じです。

于 2012-09-16T11:48:33.097 に答える
3

毎回割り当てられるわけではありませんが、反復ごとに新しい値が割り当てられます。ループは、独自のスタックフレームを持つメソッド内にあります。変数yは、そのスタックフレームに割り当てられます。

于 2012-09-16T11:50:49.457 に答える
1

ループのターンごとに新しい変数が作成されます。

ただし、int重要ではない型変数の場合。変数のスコープを小さくすることをお勧めします。そして、コンパイラはおそらく毎回同じスペースを再利用するのに十分賢いです。

于 2012-09-16T11:48:32.893 に答える
0

ループyの範囲外になるため、提示したものと同等にすることはできません。for

しかし、それはすべて実際にはコンパイラーに依存します。それが目的である場合は、2つの間のパフォーマンスを測定する必要があります。

于 2012-09-16T11:52:26.500 に答える
0

変数 y は、ループに入るたびにスタックに割り当てられるため、このスコープを離れると変数が解放されると思います。

于 2012-09-16T11:49:58.473 に答える
0

ビルド内の型では、(可視性の範囲に関係なく) 実際には問題になりません。オブジェクトの場合、オブジェクト変数が for ループの内外に留まるかどうかは (!) 重要です。次の点を考慮してください。

#include <iostream>

struct A
{

  static int i;
  void * a;

  A() : a(this) { ++i; }

};

int A::i = 0;

int main()
{

    for (int i = 0; i != 10; ++i)
    {

      A a;

      std::cout << a.a << " | " << a.i << std::endl;

    }

    return 0;
}
于 2015-06-25T15:21:05.727 に答える
0

yコード内の はローカル変数です。多くの人がこれらが割り当てられていないと思っているにもかかわらず。スタック上にスペースが予約されている場合と予約されていない場合がありますが、これは、最適化後にアドレスが取得された場合にのみ発生することが保証されています。

それ以外の場合は、スタック上にスペースがまったく予約されていない可能性があります。または、それらが使用するスタック上にいくらかのスペースがあるかもしれませんが、同じスペースが複数の変数に再利用されたり、場合によっては、呼び出している関数に引数を渡すために再利用されたりします。

スタック上にスペースが予約されている場合 (発生する場合と発生しない場合があります)、そのスペースは通常、関数のエントリ時に一度にすべて予約されます。ただし、これは実装の詳細です。それが最も速い方法なので、そのように行われます。このようにする必要はなく、実装によって現在のスタック フレームのサイズが動的に変更される可能性があります (最近のほとんどのプロセッサでは愚かなことですが、そのような実装でも問題ありません)。

于 2012-09-16T12:06:40.037 に答える