在不同范围内声明的静态变量之间的差异

Jig*_*asa 4 c++ static

在块内声明静态变量和在文件中的块外部之间有什么区别?例如,这里,静态变量a,b,c,d之间有什么区别?我们可以声明一个可以从程序的所有文件访问的静态变量吗?

    static int a;
    void getVol(..)
    { 
       static int b;
    }

    int main()
    {
       static int c;
       while(condition)
       {
           static int d;
            ....
       }
    some code here;
    return 0;
    }
Run Code Online (Sandbox Code Playgroud)

Jer*_*fin 11

最终,没有区别.忽略(暂时)静态成员函数static意味着它意味着什么 - 但是我们在不同的条件下看到它意味着什么的不同部分,因为它的一些含义也可以在没有关键字的情况下发生.

使用static关键字时,定义的对象始终具有:

  1. 静态生命周期 - 它存在于程序的整个生命周期中.
  2. 本地可见性 - 名称在声明范围之外不可见.

无论是在块内部还是外部定义的静态变量,这两者都是正确的.默认情况下,即使您不使用static关键字,也会发生一部分或另一部分,但如果您使用关键字,则始终同时获得这两部分.

static成员函数是类似的,但由于它们是函数,它们并不完全具有生命周期 - 所有函数都具有静态生命周期.静态成员函数具有本地可见性(即,其名称仅对其类可见)和某种类似"静态生命周期"的东西 - 该函数未绑定到类的实例.

编辑:对于那些关心块级静态变量初始化的特定时间的人,血淋淋的细节如下(§6.7/ 4):

具有静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)的所有块范围变量的零初始化(8.5)在任何其他初始化发生之前执行.具有静态存储持续时间的块范围实体的常量初始化(3.6.2)(如果适用)在首次输入块之前执行.

允许实现在静态或线程存储持续时间内执行其他块范围变量的早期初始化,条件是允许实现在命名空间范围内静态初始化具有静态或线程存储持续时间的变量(3.6.2).否则,在第一次控制通过其声明时初始化这样的变量; 这样的变量在初始化完成后被认为是初始化的.

因此,变量将在程序启动的早期进行零初始化.然后,如果已经指定了其他初始化,那么这将在执行通过初始化之后发生(但可能早于此发生).但是请注意,常量初始化和其他初始化之间的区别.例如,考虑这样的事情:

int g()  { return 2; }

int f() { 
    goto bypass;

    static int x = 1;
    static int y = g();

bypass:

    std::cout << x << "\n" << y;
}
Run Code Online (Sandbox Code Playgroud)

这里x是常量初始化,但y不是.由于x是常量初始化,它在进入块时初始化,所以当我们打印出它的值时,我们应该得到1.y但是,不是常量初始化,并且goto意味着执行永远不会流经其初始化 - 因此,它将保留0在任何其他初始化发生之前初始化它,因此(使用正常运行的编译器)输出将是:

1 
0
Run Code Online (Sandbox Code Playgroud)

  • 当本地静态的初始化发生时,即第一次在程序流中遇到块时,可能值得一提. (2认同)