写在前面
大家好,我是翼同学。今天文章的内容是:
- 作用域,生命周期和常用存储类型
内容
作用域
在C++中,变量分为全局变量和局部变量,这种划分依据是由变量的可见范围决定的,或者说是:作用域。
生命周期
我们把变量可以被使用的时间段称为生命周期。
不同生命周期的变量,在程序内存中的位置也不一样,通常一个程序的内存会分为:
- 代码区
- 全局数据区
- 堆区
- 栈区
如下所示:
变量在不同区域则对应不同的生命周期。
下面是程序内存的分布情况:
存储类型
生命周期只是和变量存储的位置有关,而变量的存储类型可分为两种:
- 静态存储(在程序运行时,系统对变量分配固定的存储空间)
- 动态存储(在程序运行时,系统对变量分配不固定的存储空间,即动态地分配)
一般的,变量的常用存储类型有四种:
auto
:自动变量register
:寄存器变量static
:静态变量extern
:外部变量
注意:
- 从 C++ 11 开始,
auto
关键字不再是C++
存储类说明符,且register
关键字被弃用。 - 自动变量和寄存器变量属于动态存储,外部变量和静态变量属于静态存储。
(1) auto存储
用法:
- 可用于声明函数时函数返回值的占位符
- 可用于声明变量时,系统自动根据初始化表达式自动推导该变量的类型
注意:
在C++98标准中,函数内未加存储类型说明的变量均视为自动变量(但C++11中已删除这一用法)
(2) register存储
用法:
- 可用于定义存储在寄存器中而不是 RAM (运行内存)中的局部变量.
- 可用于使用需要快速访问的变量,而不用去访问内存.
- 对于循环次数较多的变量,均可定义为寄存器变量.
注意:
- 只有局部变量才能定义为寄存器变量,因为其属于动态存储方式.
- 变量被定义
register
后不一定就真的存储在寄存器中,这取决于硬件的限制.
(3) static存储
用法:
- 修饰局部变量时,可使其在进入或离开作用域时不用被创建和销毁
- 修饰全局变量时,会使变量的作用域限制在声明它的文件内
小结:
- 静态局部变量是一种生存期为整个源程序的变量。虽然离开定义它的函数后仍无法使用它,但一旦再次调用函数时,它又可以继续使用,而且保存了前次被调用后留存的值
- 静态全局变量使其无法在同一源程序的其他源文件中使用,这可以避免在其他源文件中操作失误而引起错误。
(4) extern存储
外部变量和全局变量其实是对同一类变量的两种看法,全局变量是从作用域的角度去看,外部变量是从存储方式提出。
我们知道,一个源程序由若干个源文件组成。当我们在一个源文件中把变量说明为外部变量时,也就是用extern
去修饰,那么表示这个变量是外部的,在其他文件中已被定义过,此时系统不再为变量分配内存空间。
用法:用于两个及多个源文件共享同一个全局变量或函数(函数也能共享)
(5) 小结
当然,存储类型不止上述四种:
mutable
存储类型:仅适用于类对象,它允许对象的成员替代常量,即mutable
成员可以通过const
成员函数修改。thread_local
存储类型:使用thread_local
说明符声明的变量仅可在它在其上创建的线程上访问。它是C++11
新引入的存储类型。有且只有thread_local
关键字修饰的变量具有线程周期,这使得变量在线程开始的时候被生成,在线程结束的时候被销毁。thread_local
还可以和static
与extern
关键字联合使用。
写在最后
好了,文章的内容就到这里,感谢观看。