首页 > 其他分享 >静态变量的生命周期是多少?

静态变量的生命周期是多少?

时间:2022-10-06 15:00:50浏览次数:72  
标签:生命周期 变量 静态 int static foo 函数

何谓静态变量

在整个代码中, 静态变量 具有特定的生命周期。即使函数被多次调用,静态变量的内存也只分配一次,并且前一次调用的值被传递到下一次函数调用。它们不保存在堆栈中,而是保存在静态存储区

#include <iostream> 
using namespace std; 
  
void myFunc() 
{  
    // 在第一次func调用中初始化静态变量
    static int i = 0; 
    cout << i << " "; 
    // 值将保留在之前的func调用中,并被带到即将到来的func调用中
    i++; 
} 
int main() 
{ 
    for (int a = 0; a <= 7; a++)     
        myFunc();
    return 0; 
}
//输出:0 1 2 3 4 5 6 7 

1. 静态存储类的本地实现

- 当静态说明符应用于函数或块时,编译器会为其创建永久存储。
- 静态局部变量仅对定义它的函数或块可见。
- 静态局部变量是在函数调用之间保留其值的局部变量。
#include <stdio.h>
void demo()
{
    static int i = 4;
    {
        static int i;
        printf(" 局部: %d ",i);
        i++;
    }
    printf("非局部 : %d\n",i);
    i++;
}

int main()
{
   demo();
   demo();
}

输出:

 局部: 0 非局部 : 4
 局部: 1 非局部 : 5

2. 静态存储类的全局实现

当静态说明符应用于全局变量或函数时,编译器使该变量或函数仅对定义它的文件已知。
静态全局变量是具有内部链接的全局变量。
这意味着即使变量是全局的,但其他文件对此一无所知。
其他文件无法直接访问或更改其内容。
#include <stdio.h>
void func_1();
int a, b = 10;
int main()
{
    func_1();
    func_1();
    return 0;
}

void func_1()
{
    int a = 1;
    static int b = 100;
    printf("a = %d\n", a);
    printf("b = %d\n\n", b);
    a++;
    b++;
}

输出:

a = 1
b = 100

a = 1
b = 101

一个疑问

如果个变量被声明为 static在函数的范围内,它只初始化一次,并在函数调用之间保留其值。 它的寿命究竟是多少? 什么时候调用它的构造函数和析构函数?

void foo() 
{ 
    static string plonk = "When will I die?";
}

函数的生命周期 static变量在程序流第一次遇到声明时开始 ,并在程序终止时结束。 这意味着运行时必须执行一些记录,以便只有在实际构建时才将其销毁。
此外,由于标准规定静态对象的析构函数必须按照其构造完成的相反顺序运行 ,而构造顺序可能取决于具体程序运行,因此必须考虑构造顺序。

struct emitter {
    string str;
    emitter(const string& s) : str(s) { cout << "Created " << str << endl; }
    ~emitter() { cout << "Destroyed " << str << endl; }
};

void foo(bool skip_first) 
{
    if (!skip_first)
        static emitter a("in if");
    static emitter b("in foo");
}

int main(int argc, char*[])
{
    foo(argc != 2);
    if (argc == 3)
        foo(false);
}
    C:>sample.exe
    Created in foo
    Destroyed in foo

    C:>sample.exe 1
    Created in if
    Created in foo
    Destroyed in foo
    Destroyed in if

    C:>sample.exe 1 2
    Created in foo
    Created in if
    Destroyed in if
    Destroyed in foo

题外说明:
编译器通常使用隐藏标志变量来指示本地静态变量是否已经初始化,并且在函数的每个条目上都会检查此标志。 显然这是一个小的性能损失,但更令人担忧的是这个标志不能保证是线程安全的。
如果您有如上所述的本地静态,并且 foo从多个线程调用,你可能有竞争条件导致 plonk初始化不正确甚至多次。 此外,在这种情况下 plonk可能会被与构造它的线程不同的线程破坏。
尽管标准说了什么,但我对局部静态破坏的实际顺序非常谨慎,因为您可能会不知不觉地依赖静态在它被破坏后仍然有效,这真的很难追踪。
————————————————
1.what is the lifetime of a static variable in a c function
2.C++简单依赖注入
[参考2] 由于c++ 98没有对多线程的引用,因此在多线程环境中如何表现是未指定的,并且可能会像Roddy提到的那样有问题。
[参考3] 在c++ 11静态是以线程安全的方式初始化的,这也被称为magic static。
————————————————

标签:生命周期,变量,静态,int,static,foo,函数
From: https://www.cnblogs.com/zachlili/p/16757598.html

相关文章

  • 字符串,变量,常量,转义字符,学习笔记
    字符串:编程中表示文本的数据类型。所有用引号括起来的数据,都是字符串。在编程语言中,我们用字符串这种数据类型来表示和存储文本。在引号的内部,数据可以是英文、中文、数字......
  • 连续型随机变量:概率密度
    分布函数:https://www.cnblogs.com/tsuish/p/16731610.html分布函数的一些常用方法概率密度:(1)均匀分布(2)指数分布(3)正态分布......
  • 离散型随机变量:分布律
    离散型随机变量:有些随机变量,它全部可能取到的值是有限个或可列无限个,这种随机变量称为离散型随机变量。分布律:(1)0-1分布(2)二项分布(3)泊松分布......
  • 今天重新学习java基础的时候遇到了一个好玩的问题。换了环境变量jdk还是显示原来版本
    今天学习ES,需要用到更高版本的jdk(我以前用的是1.8),所以要更改以前的jdk设置,总体步骤如下:1.下载jdk-11,解压2.打开环境变量配置,把以前配置的JAVA_HOME的改为新jdk-11的路径......
  • 【笨方法学python】ex19 - 函数和变量
    代码如下:点击查看代码#-*-coding:utf-8--*-#函数和变量defcheese_and_crackers(cheese_count,boxs_of_crackers): print"Youhave%dcheeses!"%cheese_cou......
  • Python学习(三)win7 下添加python环境变量
    我的电脑--属性--高级系统设置;环境变量--新建,变量名:“PYTHONHOME”,变量值:python的安装路径;找到Path--编辑,在变量值的最后边添加“;%PYTHONHOME%;%PYTHONHOME%\Scrip......
  • rockylinux9.0静态ip配置
    方式一修改NetworkManager配置文件(ens33为我的网卡名)修改完成后,执行命令如下,使配置生效#重新加载配置文件[root@k8s-master~]#nmcliconnectionload/etc/NetworkM......
  • SparkCore:累加器和广播变量
    累加器累加器(分布式共享只写变量):用来把Executor端变量信息聚合到Driver端。在Driver程序中定义的变量,在Executor端的每个Task都会得到这个变量的一份新的副本,每......
  • Vue3.x 组合式api的生命周期钩子
    Vue3组合式api的生命周期beforeCreatecreated,setup语法糖模式(组合式api)是没有这两个生命周期的,用setup去代替onBeforeMount获取不到DOM,onMounted可以获取DOMon......
  • 02.字面量和变量
    字面量字面量其实就是一个值。像1、2、3这种数字,又像是”abc”、”你好”、”锄禾日当午”这种字符串,再有就是true、false这些布尔值,都是字面量。所谓的字面量,指这些值......