当前位置:网站首页>全局变量和静态变量的初始化

全局变量和静态变量的初始化

2022-07-05 06:36:00 一只嵌入式爱好者

全局变量、static变量初始化时间

静态局部变量

首先,静态局部变量和全局变量一样,数据都存放在全局区域,所以在主程序之前,编译器已经为其分配好了内存,但在C和C++中静态局部变量的初始化节点又有点不太一样。

在C中,初始化发生在代码执行之前,编译阶段分配好内存之后,就会进行初始化,所以我们看到在C语言中无法使用变量对静态局部变量进行初始化,在程序运行结束,变量所处的全局内存会被全部回收。

而在C++中,初始化时在执行相关代码时才会进行初始化,主要是由于C++引入对象后,要进行初始化必须执行相应构造函数和析构函数,在构造函数或析构函数中经常会需要进行某些程序中需要进行的特定操作,并非简单地分配内存。所以C++标准定为全局或静态对象是有首次用到时才会进行构造,并通过atexit()来管理。在程序结束,按照构造顺序反方向进行逐个析构。所以在C++中是可以使用变量对静态局部变量进行初始化的。

全局变量、文件域的静态变量和类的静态成员变量在main执行之前的静态初始化过程中分配内存并初始化;局部静态变量(一般为函数内的静态变量)在第一次使用时分配内存并初始化。这里的变量包含内置数据类型和自定义类型的对象。

全局变量

根据 C++ 标准,全局变量的初始化要在 main 函数执行前完成,常识无疑,但是这个说法有点含糊,main 函数执行前到底具体是什么时候呢?是编译时还是运行时?答案是既有编译时,也可能会有运行时(seriously), 从语言的层面来说,全局变量的初始化可以划分为以下两个阶段(c++11 N3690 3.6.2):

不要写出和编译顺序相关的程序

对于不同编译单位的全局变量,其初始化的顺序没有任何的保证,因此对不同编译单位里的全局变量,在它们的初始化顺序之间建立依赖性都是不明智的。此外也没办法捕捉到全局变量初始化抛出的异常,一般来说要减少全局变量的使用,特别是限制那些要求复杂初始化的全局变量。so:
1、尽量不用全局变量
2、用静态变量,通过访问器进行访问
例如:全局变量

int   a   =   5;  
int   b   =   a;  

如果a,和b定义在同一个文件里,那没什么问题,结果b等于5。如果a和b定义在不同文件里,就不能保证b也等于5,也就是说不能保证a先初始化。事实上,除了在同一个文件定义的全局对象的初始化是按照定义次序来进行的之外,其他全局或静态变量之间的初始化次序没有任何保障。解决这种问题的方法是不直接使用全局变量,而改用一个包装函数来访问,例如

  int   get_a()  
  {
      
          static   int   a   =   5;  
          return   a;  
  }  
  int   get_b()  
  {
      
          static   int   b   =   get_a();  
          return   b;  
  }   

这样的话,无论get_a和get_b是否定义在同一个文件中,get_b总是能够返回正确的结果,原因在于,函数内部的静态变量是在第一次访问的时候来初始化。

任何时候,如果在不同的被编译单元中定义了"非局部静态对象",并且这些对象的正确行为依赖于它们被初始化的某一特定顺序,就会产生问题。你绝对无法控制不同被编译单元中非局部静态对象的初始化顺序。对于函数中的静态对象(即"局部"静态对象)它们在函数调用过程中初次碰到对象的定义时被初始化…

总结

1、静态变量的初始化是在编译时进行,变量的赋值是在函数或程序运行时进行。
2、静态变量只初始化一次,但可以通过赋值的方式多次修改静态变量的值。
3、全局变量和静态变量 在进入 main 前被初始化

原网站

版权声明
本文为[一只嵌入式爱好者]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_45905650/article/details/125509756