Skip to content

Latest commit

 

History

History
17 lines (9 loc) · 4.08 KB

File metadata and controls

17 lines (9 loc) · 4.08 KB

变量的存储类型

变量的存储类型是指存储变量值的内存类型。变量的存储类型决定变量何时创建、何时销毁以及它的值保持多久。有三个地方可以用于存储变量:普通内存、运行时堆栈、硬件寄存器。在这三个地方存储的变量具有不同的特性。

变量缺省存储类型取决于它的声明位置。凡是在任何代码块之外声明的变量总是存储于静态内存中,也就是不属于堆栈的内存,这类变量称为静态变量。对于这类变量,程序员无法为它们指定其他存储类型。静态变量在程序运行之前创建,在程序的整个执行期间始终存在。它始终保持原先的值,除非给它赋一个不同的值或者程序结束。

在代码块内部声明的变量的缺省存储类型是自动的,也就是说它存储与堆栈中,称为自动变量。有一个关键字 auto 就是用于修饰这种存储类型的,但它极少使用,因为代码块中的变量在缺省情况下就是自动变量。在程序执行到声明自动变量的代码块时,自动变量才被创建,当程序的执行流离开该代码块时,自动变量便自行销毁。如果该代码块被多次调用,例如一个函数被数次调用,这些自动变量每次都会被重新创建。当代码再次执行时,这些自动变量在堆栈中所占据的内存位置有可能与原先的位置相同,也可能不同。即使它们所占据的位置相同,程序员也不能保证这块内存同时不会有其他的用途。因此,可以说自动变量在代码块执行完毕后就消失。当代码块再次被执行是,它们的值一般并不是上次执行时的值。

对于在代码块内部声明的变量,如果给它们加上关键字 static ,可以使它们的存储类型从自动变为静态。具有静态存储类型的变量在整个程序执行过程中一直存在,而不仅仅在声明它的代码块的执行时存在。注意,修改变量的存储类型并不表示修改该变量的作用域,它仍然只能在该代码块内部按名字访问。函数的形式参数不能声明为静态,因为实参总是在堆栈中传递给函数,用于支持递归。

最后,关键字 register 可以用于自动变量的声明,提示它们应该存储于机器的硬件寄存器而不是内存中,这类变量称为寄存器变量。通常,寄存器变量比存储于内存的变量访问起来效率更高。但是,编译器并不一定要理睬 register 关键字,如果有太多的变量被声明为 register ,它只选择前几个实际存储于寄存器中,其余的就按普通自动变量处理。如果一个编译器自己具有一套寄存器优化方案,它也可能忽略 register 关键字,其依据是由编译器决定哪些变量存储于寄存器中比人脑的决定更为合理一些。

在典型的情况下,程序员希望把使用频率最高的那些变量声明为寄存器变量。在有些计算机中,如果把指针声明为寄存器变量,程序的效率将得到提高,尤其是那些频繁执行间接访问操作的指针。可以把函数的形式参数声明为寄存器变量,编译器会在函数的起始位置生成指令,把这些值从堆栈中复制到寄存器中。但是,完全有可能,这个优化措施所节省的时间和空间的开销还抵不上复制这几个值所用的开销。

寄存器变量的创建和销毁时间和自动变量相同,但它需要一些额外的工作。在一个使用寄存器变量的函数返回之前,这些寄存器先前存储的值必须恢复,确保调用者的寄存器变量未被破坏。许多机器使用运行时堆栈来完成这个任务。当函数开始执行时,它把需要使用的所有寄存器的内容都保存到堆栈中,当函数返回时,这些值再复制回寄存器中。

在许多机器的硬件实现中,并不为寄存器指定地址。同样,由于寄存器值的保存和恢复,某个特定的寄存器在不同的时刻所保存的值不一定相同。基于这个理由,机器并不向程序员提供寄存器变量的地址。