【问题标题】:Local variables defined inside for loops in C++在 C++ 的 for 循环中定义的局部变量
【发布时间】:2012-09-16 11:44:18
【问题描述】:

在以下一段 C++ 代码中:

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

        //Some statements
    }

变量 (y) 是在每次循环迭代时分配,然后在迭代完成时释放,还是为所有循环迭代分配一次?

上面提到的代码是否等同于以下代码?:

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

        //Some statements
    }

【问题讨论】:

标签: c++ variables for-loop local


【解决方案1】:

当函数被调用时,它将在堆栈上分配一次。在性能方面,这两种方式之间没有区别(但请记住,在最后一种方式中,y 在循环之后仍将在范围内)。变量似乎在每次迭代之间被创建和销毁(因此它在迭代之间“丢失”其值)是由编译器创建的行为;实际内存位置始终相同。

【讨论】:

    【解决方案2】:

    不是每次都分配,而是在每次迭代中分配一个新值。循环在一个方法中,该方法有自己的堆栈帧。变量 y 在该堆栈帧中分配。

    【讨论】:

      【解决方案3】:

      循环中的每一轮都会创建一个新变量。

      但是,对于不重要的int 类型变量。最好为变量设置一个较小的范围。而且编译器可能足够聪明,每次都可以重用相同的空间。

      【讨论】:

        【解决方案4】:

        我认为每次进入循环时变量 y 都会在堆栈上分配,因为变量在离开此范围时将被释放。

        【讨论】:

        • 在循环内,它仍然在作用域内,所以它不会取消分配堆栈。
        【解决方案5】:

        它不能等同于您提供的那个,因为y 将超出for 循环的范围。

        但这完全取决于编译器,如果这是你所追求的,你必须衡量两者之间的性能。

        【讨论】:

          【解决方案6】:

          代码中的y 是一个局部变量。尽管许多人认为这些没有分配。它们可能在堆栈上为它们保留了一些空间,也可能没有,但只有在优化后,它们的地址被占用时才能保证发生这种情况。

          在所有其他情况下,它们可能根本没有在堆栈上保留空间。或者他们使用的堆栈上可能有一些空间,但相同的空间被重复用于多个变量,甚至在某些情况下,用于将参数传递给您正在调用的函数。

          当在堆栈上保留空间时(可能会或可能不会发生),通常会在函数进入时立即保留所有空间。然而,这是一个实现细节。这样做是因为它是最快的方法。没有要求以这种方式完成,并且实现可以很好地动态改变当前堆栈帧的大小(在大多数现代处理器上这样做是愚蠢的,但这样的实现仍然是正确的)。

          【讨论】:

            【解决方案7】:

            对于内置类型,这并不重要(无论可见性范围如何)。对于对象,对象变量是否留在/退出 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;
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2014-08-06
              • 2019-09-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-12-20
              • 1970-01-01
              相关资源
              最近更新 更多