'静态' C ++中的关键字

时间:2012-03-20 22:14:38

标签: c++ static

我意识到它在超出范围后保留了价值(但变得无法访问),但我有几个问题。

  1. 当人们说在范围之外无法访问时,只是意味着你不能在其识别范围之外改变价值(它会出错)?

  2. 我在考虑这段代码:

    #include "iostream"
    
    void staticExample();
    
    int main()
    {
        staticExample();
    
        return 0;
    }
    
    void staticExample()
    {
        for (int i = 1; i <= 10; ++i)
        {
            static int number = 1;
            std::cout << number << "\n";
    
            ++number;
        }
    }
    
  3. 我想,在循环的每次迭代中,我将'number'变量设置为1.正如我第一次预期的那样,它打印了1,2,3 .. 10.编译器是否认识到将其设置为1的行是声明并忽略其“更改”?

5 个答案:

答案 0 :(得分:3)

调用staticExample两次,看看输出会发生什么。这将有助于您了解适用于局部变量的“静态存储”。

#include <iostream> 

void staticExample()
{
    static int number = 1;

    for (int i = 1; i <= 10; ++i)
    {
        std::cout << number << "\n";
        ++number;
    }
}

int main()
{
    staticExample();  // begins counting at 1
    staticExample();  // begins counting at 10

    return 0;
}

输出:

1 2 3 4 五 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

我曾经读过一个我喜欢的报价,“你有堆栈存储,你有堆存储,但你也有另一种类型的存储。它被称为静态,它既不在堆栈上,也不在堆中。”不是逐字的,而是类似的。

答案 1 :(得分:2)

该对象生动一次,因此初始化一次。初始化不是分配。 (IINA?いい,な!)

答案 2 :(得分:1)

static变量(这也适用于static class个成员)仅初始化一次 - 全球。即使是第一次通过声明初始化的作用域,通常也会忽略初始化,尽管可能有一些编译器会以不同的方式执行 - 因此它依赖于编译器。

原因:初始化通常在之前发生你的main()函数被调用,甚至经常会反映在可执行文件/二进制文件中,因为静态数据被写入预先初始化的地址链接时。这意味着即使在第一段代码(将调用您的static的C运行时部分)运行之前,大多数时间main()数据也是有效的。

除了指针/引用别名之外,没有办法在其直接范围之外访问这样的变量(周围的大括号{})。

来自here

6.7声明声明

  

允许实现执行早期初始化   具有静态或线程存储持续时间的其他块范围变量   在允许实施的相同条件下   静态初始化具有静态或线程存储的变量   命名空间范围内的持续时间(3.6.2)。

我在逆向工程中遇到的大多数实现似乎都在使用它,特别是因为以下内容也适用:

3.7.1静态存储时间

  

如果具有静态存储持续时间的变量具有初始化或a   具有副作用的破坏者,即使它也不会被消除   似乎未使用,除了类对象或其复制/移动可能   按照12.8的规定予以淘汰。

...这意味着让static的行为类似于它在C中的行为是有意义的 - 即如果初始化是在编译时定义的,则预先初始化其内容。

当声明变量但未在声明时初始化时,许多编译器将以零或一些幻数(例如在调试版本中)进行初始化。

答案 3 :(得分:0)

  1. 这只意味着像这样的代码会导致编译错误消息:

    {
        static int x;
        x = 5;
    }
    x = 6;  // Compiler error here!  We're outside the scope that x was declared in.
    

    但这并不意味着你无法访问它。例如:

    int *p = NULL;
    {
        static int x;
        x = 5;
        p = &x;
    }
    *p = 6;  // This is fine
    
  2. 静态变量只初始化一次;第一次到达。

答案 4 :(得分:0)

  

当人们说它在范围之外无法访问时,它只是意味着你不能在它识别范围之外改变价值(它会错误)?

不,这不是范围的意思。当你使用名称&#34;在范围之外&#34;这意味着该名称不会解析为相关范围内的实体。该名称可能会解析为其他对象,或者可能是无效的名称,具体取决于上下文。

只要对象的生命周期已经开始并且还没有结束,对象就可以通过各种方式通过其变量范围之外的表达式来改变,例如它的地址被传递到存储它的另一个函数,随后这个存储的地址用于改变对象。

在您的代码示例中,= 1是初始值设定项,而不是赋值。它在初始化变量时使用,当对象被声明为static时,仅在第一次执行通过声明语句时发生。