【问题标题】:Static int in function函数中的静态 int
【发布时间】:2013-04-27 02:24:12
【问题描述】:

我遇到了这段代码:

void function(int nextFoo)
{
    static int lastFoo = nextFoo; 
    if (nextFoo != lastFoo) 
    {
         // is this possible?
    }
    lastFoo = nextFoo;
}

coder 认为lastFoo 只设置在第一次运行,最后一行,对吗?我认为(但不知道) if 块中的代码永远不会运行,但找不到验证。

【问题讨论】:

  • nextFoo 是由调用者设置的...也许你说的是lastFoo 的设置时间?
  • @BenVoigt 是的,糟糕,已修复。

标签: c++ function static


【解决方案1】:

Static 是一个存储类,它告诉编译器该变量不是每次进入和离开函数时都会创建/销毁的自动变量。

来自 K&R C 编程语言(第 2 版)

A4.1 存储类

有两种存储类:自动和静态

...

静态对象可以是一个方块的本地对象,也可以是所有方块的外部对象,但是 在任何一种情况下,在退出和重新进入函数和块时都保留它们的值。

所以是的,if 声明是完全合法的。再次调用该函数时,该变量可能具有不同的值。

【讨论】:

    【解决方案2】:

    编码者认为nextFoo只是在第一次运行时设置的,最后一行,对吗?

    是的。 static 局部变量只初始化一次(而不是每次输入函数时)。在 C++11 中,这也保证以线程安全的方式发生。根据 C++11 标准的第 6.7/4 段:

    [...] 如果控制进入 在变量初始化的同时声明,并发执行应等待 完成初始化 [...]

    注意,如果static对象的初始化抛出异常,下次进入function()时会重新尝试初始化(在这种情况下不相关,因为int的初始化不能扔)。从上面引用的同一段中:

    [...] 如果初始化通过抛出异常退出,则初始化 不完整,所以下次控制进入声明时会再次尝试。 [...]

    【讨论】:

    • 最后一行每次调用函数时都会设置。
    • @MM.: 是的,但是每次你可以用不同的参数调用函数
    • 有谁知道哪些编译器实现了新的并发要求?
    【解决方案3】:

    简单的答案是,是的lastFoo 只会在这里设置第一次:

    static int lastFoo=nextFoo;
    

    但这足以作为一个测试来了解它是如何为你自己工作的。当然在函数的末尾lastFoo会被最终赋值:

    #include <iostream>
    
    void function(int nextFoo)
    {
        static int lastFoo=nextFoo; 
    
        std::cout << "lastFoo: " << lastFoo << std::endl ;
    
        if (nextFoo!=lastFoo) 
        {
             std::cout << "here" << std::endl ;
        }
        lastFoo=nextFoo;
    }
    
    int main()
    {
        function(10) ;
        function(11) ;
    
    }
    

    【讨论】:

      【解决方案4】:

      块中的代码可以运行;以下示例打印hello

      #include <iostream>
      
      using namespace std;
      
      void function(int nextFoo)
      {
          static int lastFoo=nextFoo; 
          if (nextFoo!=lastFoo) 
          {
              cout << "hello" << endl;
          }
          lastFoo=nextFoo;
      }
      
      int main()
      {
          function(1);
          function(2);
      
          return 0;
      }
      

      【讨论】:

        【解决方案5】:

        当然可以。静态初始化只发生一次。下次调用该函数时,不再进行初始化。

        (事实上,初始化甚至是无竞争的 :-)。)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-28
          相关资源
          最近更新 更多