【问题标题】:On local and global static variables in C++关于 C++ 中的局部和全局静态变量
【发布时间】:2012-08-24 14:09:39
【问题描述】:

C++ 入门说

每个局部静态变量在第一次之前初始化 执行通过对象的定义。局部静力学是 函数结束时不会被销毁;它们在编程时被破坏 终止。

局部静态变量与全局静态变量有什么不同吗?除了声明它们的位置之外,还有什么不同?

void foo () {   
    static int x = 0;
    ++x;

    cout << x << endl;
}

int main (int argc, char const *argv[]) {
    foo();  // 1
    foo();  // 2
    foo();  // 3
    return 0;
}

比较

static int x = 0;

void foo () {   
    ++x;

    cout << x << endl;
}

int main (int argc, char const *argv[]) {
    foo();  // 1
    foo();  // 2
    foo();  // 3
    return 0;
}

【问题讨论】:

    标签: c++ static


    【解决方案1】:

    区别在于:

    • 名称只能在函数内部访问,没有链接。
    • 它在第一次执行到达定义时被初始化,不一定在程序的初始化阶段。

    第二个区别对于避免静态初始化顺序失败很有用,在这种情况下,全局变量可以在它们被初始化之前被访问。通过将全局变量替换为返回对局部静态变量的引用的函数,您可以保证它在任何访问它之前被初始化。 (但是,仍然不能保证它不会在任何东西完成访问它之前被销毁;如果您认为您需要一个全局可访问的变量,您仍然需要非常小心。请参阅 cmets 以获取 link 以帮助情况。)

    【讨论】:

    【解决方案2】:

    它们的范围不同。文件中的任何函数都可以访问全局范围的静态变量,而函数范围的变量只能在该函数内访问。

    【讨论】:

    • @DavidRodríguez-dribeas: '在编译单元 s 中未定义。在编译单元中,顺序被很好地定义为声明的顺序。
    • @LokiAstari:你是对的......我在评论中太含糊了:)
    【解决方案3】:

    希望这个例子有助于理解静态局部变量和全局变量之间的区别。

    #include <iostream>
    
    using namespace std;
    
    static int z = 0;
    
    void method1() {
        static int x = 0;
        cout << "X : " << ++x << ", Z : " << ++z << endl;
    }
    
    void method2() {
        int y = 0;
        cout << "Y : " << ++y << ", Z : " << ++z << endl;
    }
    
    int main() {
        method1();
        method1();
        method1();
        method1();
        method2();
        method2();
        method2();
        method2();
        return 0;
    }
    

    输出:

    X : 1, Z : 1
    X : 2, Z : 2
    X : 3, Z : 3
    X : 4, Z : 4
    Y : 1, Z : 5
    Y : 1, Z : 6
    Y : 1, Z : 7
    Y : 1, Z : 8
    

    【讨论】:

      【解决方案4】:

      真名是:

      static storage duration object.
      

      全局变量也是“静态存储持续时间对象”。与全局变量的主要区别在于:

      • 直到第一次使用它们才被初始化
        注意:构造过程中的异常意味着它们没有被初始化,因此没有被使用。
        所以下次输入函数时会重试。
      • 它们的可见性受其范围的限制
        (即它们在函数之外是看不到的)

      除此之外,它们就像其他“静态存储持续时间对象”。

      注意:与所有“静态存储持续时间对象”一样,它们会以与创建相反的顺序被销毁。

      【讨论】:

      • 我在阅读规范时是否误读了该规范,因为静态局部变量可能与其他静态变量一起被初始化,并且可能不会延迟到第一次调用? (在某些情况下,C++11 §6.7.4 似乎转发到 §3.6.2 并允许这样做)
      • 3.7.1 静态存储时长(注:6.7描述了局部静态变量的初始化)。 6.7 声明语句(具有静态存储持续时间的块范围实体的常量初始化(3.6.2),如果适用,在首次进入其块之前执行。...否则初始化此类变量第一次控制通过它的声明常量初始化(3.6.2)具有静态存储持续时间的块范围实体;这样的变量在其初始化完成时被认为已初始化。)
      【解决方案5】:

      主要或最严重的区别是初始化时间。局部静态变量在第一次调用声明它们的函数时被初始化。全局变量在调用 main 函数之前的某个时间点初始化,如果全局静态变量很少,它们会以未指定的顺序初始化,这可能会导致问题;这被称为静态初始化惨败。

      【讨论】:

        【解决方案6】:

        在您的第一个代码块中,x 是 foo() 函数的本地函数,这意味着它是在 foo() 中创建并在 cout 之后函数结束时销毁的。但是,在您的第二个块中, x 是全局的,这意味着 x 的范围是整个程序。如果你想在 int main 下你可以 cout

        【讨论】:

          【解决方案7】:
          1. 程序中的所有函数都知道它们,而全局 变量只在有限的范围内是已知的。
          2. 全局静态变量可以在程序启动之前初始化,而局部静态变量可以在执行到达点时初始化。

          【讨论】:

            猜你喜欢
            • 2015-10-04
            • 1970-01-01
            • 2023-03-29
            • 2012-06-18
            • 1970-01-01
            • 2015-06-12
            • 2011-04-27
            • 1970-01-01
            • 2022-01-28
            相关资源
            最近更新 更多