存储持续性,作用域和链接性

自动存储持续性

概念:在函数定义中声明的变量(包括函数参数)的存储持续性为自动的。他们在程序开始执行其所属的函数或代码块时被创建,在执行完函数或代码块时,他们使用的内存被释放。

  • 在默认情况下,函数中声明的函数参数和变量的存储持续性为自动的,作用域为局部的,没有链接性。当程序开始执行某函数的代码块时,将为该代码块内的变量分配内存,当函数结束时,这些变量都将消失(注意,执行到代码块时,将为变量分配内存,但其作用域的起点为其声明位置)。
  • 若代码块的外部先声明了一个变量,内部随后声明了一个同名变量,则程序执行内部代码块中的语句时,将同名变量解释为局部代码块变量,即代码块内部定义的变量隐藏了先前外部定义的变量。

 自动变量和栈

由于自动变量的数目随着函数额开始和结束而增减,因此程序必须在运行时对自动变量进行管理。常用的方法是留出一段内存,并将其视为栈,以管理变量的增减。之所以称之为栈,是由于新数据被象征性的放在原有的数据的上面(也就是说,在相邻的内存单元中,而不是在同一个内存单元中,当程序使用完后,将其从栈中删除。栈的默认长度取决于实现,但编译器通常提供改变栈长度的选项。程序使用两个指针来跟踪栈,一个指针指向栈底——栈的开始位置,另一个指针指向堆顶——下一个可用内存单元。当函数被调用时,其自动变量将被加入到栈中,栈顶指针指向变量后面的下一个可用的内存单元。函数结束时,栈顶指针被重置为函数被调出前的值,从而释放新变量使用的内存。

在内存中,栈的生长方向是向上的,即入栈操作时,需要将栈顶指针sp减一。函数调用将其参数的值放在栈顶,然后重新设置栈顶指针。被调用的函数根据其形参描述来确定每个参数的地址。

寄存器变量

关键字register显示的指出变量是自动的,只能用于原本就是自动的变量,使用他的唯一原因是,指出程序员想要一个自动变量,这个变量的名称可能与外部变量相同。这与auto以前的用途完全相同。然而,保留关键字register的重要原因是,避免使用了该关键字的现有代码非法。 


静态存储持续性

在函数定义外定义的变量和使用关键字static定义的变量的存储持续性都为静态。他们在程序整个运行过程中都存在。

C++为静态存储持续性变量提供了3种链接性:外部链接性(可在其他文件中访问),内部链接性(只能在当前文件中访问)和无链接性(只能在当前函数或代码块中访问)。这三种链接性都在整个程序执行期间存在,与自动变量相比,他们的寿命更长。由于静态变量的数目在程序运行期间是不变的,因此程序不需要使用特殊的装置(如栈)来管理他们。编译器将分配固定的内存块来存储所有的静态变量,这些变量在整个程序执行期间一直存在。如果没有显示的初始化静态变量,编译器将把它设为0;在默认情况下,静态数组和结构将每个元素或成员的所有位都设置为0,称为零初始化(zero-initialized)。

初始化

  • 创建链接性为外部的静态持续变量,必须在代码块的外面声明它。
  • 创建链接性为内部的静态持续变量,必须在代码块的外面声明他,并使用static限定符。
  • 创建没有链接性的静态持续变量,必须在代码块内声明他,并使用static限定符。如函数中的静态变量。

 

静态持续性,外部链接性

链接性为外部的变量通常简称为外部变量,他们的存储持续性为静态的,作用域是整个文件。外部变量是在函数外部定义的,因此对所有函数而言都是外部的,因此外部变量也称全局变量。

单定义规则:一方面,在每个使用外部变量的文件中,都必须声明它;另一方面,C++有“单定义规则”,即变量只能有一次定义。

C++提供了两种变量声明:一种是定义声明,它给变量分配存储空间;另一种是引用声明,使用关键字extern,不给变量分配存储空间,引用已有的变量。

double up; //definition up is 0
extern int blem; //blem defined elsewhere
extern char gr = 'z'; //definition because initialized

如果在多个文件中使用外部变量,秩序在一个文件中包含该变量的定义(单定义规则),但在使用该变量的其他所有文件中,都必须使用关键字extern声明它。

静态持续行,内部链接性

 将static限定符用于作用域为整个文件的变量时,该变量的链接性为内部的,只能在本文件使用,不能被其他文件使用。

静态存储持续性,无链接性

无链接性必为局部变量,将static限定符用于在代码块中定义的变量,该变量只能在该代码块中使用,但一直存在。如果初始化了静态局部变量,则程序只在启动时进行一次初始化,以后再调用函数时,不会像自动变量那样再次被初始化。


线程存储持续性

当前,多核处理器很常见,这些CPU可同时处理多个执行任务。这让程序能够将计算放在可并行处理的不同线程中。如果变量时使用关键字thread_local声明的,择其生命周期所属的线程一样长。


动态存储持续性

用new运算符分配的内存将一直存在,知道使用delete运算符将其释放或程序结束为止。这种内存的存储持续性为动态,又是被称为自由存储(free store)或堆(heap)。

通常编译器使用三块独立的内存:一块用于静态变量(可能再细分),一块用于自动变量(栈),另一块用于动态存储(堆)。


作用域和链接

作用域(scope)描述了名称再文件(翻译单元)的多大范围内可见。

链接性(linkage)描述了名称如何在不同单元间共享。链接性为外部的名称在文件间共享,链接性为内部名称只能由一个文件中的函数共享。自动变量的名称没有链接性,因为他们不能共享。


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

若水菱花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值