【问题标题】:Declaring static and non-static variables inside loops在循环内声明静态和非静态变量
【发布时间】:2021-07-25 18:24:31
【问题描述】:

我想在循环中使用一个变量,但我不希望在每次迭代时都重新声明它。显然我可以在循环外声明它,但我想知道如果我在循环内将它声明为 static 会发生什么。

为了测试这一点,我在 while 循环中声明了一个 static 和一个 非静态 变量,然后在每次迭代时打印它们的内存地址。我希望 non-static 变量的地址不断变化,而 static 的地址保持不变。

  while (true)
  {
    int var1;
    static int var2;

    cout << &var1 << "\n"
         << &var2 << endl;
  }

结果:令我惊讶的是,两个变量的地址保持不变。

  1. 这是某种编译器优化,还是我错误地认为重新声明 non-static 变量应该在每次迭代中产生不同的地址?我正在使用没有优化标志的 gcc 9.3.0
  2. static 变量是否是在循环外声明 非静态 变量的好选择(假设我在外部范围内不需要它并且我' m 不担心变量会保留其最后一个值,以防以后再次进入循环)?

【问题讨论】:

  • 关于“好选择”:取决于您需要变量的用途。你打算如何使用它?你有什么具体的想法吗?
  • 尝试将显示的代码放在不同的函数中,然后直接从main调用它从另一个函数(由main调用)。那么你应该会看到不同。
  • @Someprogrammerdude 不同之处在于范围,当变量第二次进入循环时,它将以其最后一个值开始。我明白了,但还有其他问题吗?
  • 不是范围,而是生命周期var1var2 具有完全相同的范围。 var2static storage duration 意味着它的生命周期将是整个程序的完整运行时间。 Local static variables 也保证为零初始化,除非以其他方式显式初始化,并且初始化(并且仅初始化)保证是线程安全的并且只发生一次。
  • static 选项将为代码添加一些同步,因为函数static 对象保证在多线程代码中只被初始化一次。

标签: c++


【解决方案1】:

在循环的每次迭代中都会创建和销毁非静态变量。

碰巧它每次都是在同一个内存地址上创建的。

但是,依赖于此,并依赖于在循环迭代中保留变量的内容将是未定义的行为。

【讨论】:

    【解决方案2】:

    期望编译器改变局部变量的地址是不合理的:只有有限数量的可能地址(264)但是你的循环是无限的,所以地址必须以某种方式重复。而最简单的重复方法就是立即重复。

    关于static 是否足够好 - 取决于使用情况。然而,static 在大多数情况下可能并不比本地更好,否则static 将是默认行为。

    【讨论】:

      【解决方案3】:

      static 变量显然只初始化一次,因此期望地址保持不变是完全合理的。

      现在,对于非静态变量。在循环中声明变量时,它将在循环的下一次迭代之前被销毁。这意味着下次循环运行时内存将再次可用。因此,变量可能具有相同的地址。

      事实上,编译器可能必须这样做,因为它无法知道循环将运行多少次。由于计算机只有有限的内存,我们不能在每次迭代时分配一个新变量。

      一种思考方式是变量实际上是在循环之外创建的。事实上,某些语言(例如 Pascal)实际上要求您在函数的开头声明所有变量。只是在循环中声明变量会稍微减少认知负担,这就是大多数语言支持它的原因。但最终,这一切都归结为同一件事。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多