C++变量存储类型与标识符生命期

来源:互联网 发布:中国邮政数据传媒中心 编辑:程序博客网 时间:2024/05/21 17:23

变量存储类型

存储类型决定了变量的生命期,变量生命期指从获得空间到空间释放之间的时期。

存储类型的说明符有四个:auto, register, staticextern。前两者称为“自动”类型,后两者分别为“静态”和“外部”类型。

1、自动存储类型:包括自动变量和寄存器变量。

  • 自动变量:用auto说明的变量,通常auto省略。前面提到的局部变量都是自动类型。其生命期开始于块的执行,结束于块的结束。自动变量的空间分配在栈中,在程序运行过程中,块开始执行时系统自动分配空间(未初始化时值为随机数),块执行结束时系统自动释放空间。因此,自动变量的生命期和作用域是一致的。
  • 寄存器变量:说明时用register修饰,如:register int i; 系统将这样说明的变量尽可能保存在寄存器中,以提高程序运行速度。但不同的编译器对哪些变量可以说明为寄存器变量有不同的规定,而且一般的编译器都会对寄存器的使用进行优化,所以不提倡使用寄存器变量。

2、静态存储类型: 用static说明的变量称为“静态变量”。

  • 静态变量均存储在全局数据区,如果程序未显式给出初始化值,系统自动初始化为全0,且初始化只进行一次;
  • 静态变量占有的空间要到整个程序执行结束才释放,故静态变量具有全局生命期。根据定义的位置不同,还分为“局部静态变量”和“全局静态变量”,也称“内部静态变量”和“外部静态变量”。其中,局部静态变量是定义在块中的静态变量,当块第一次被执行时,编译器在全局数据区为其开辟空间并保存数据,该空间一直到整个程序结束才释放。该变量具有局部作用域,但却具有全局生命期。

【例3.10】 自动变量与局部静态变量的区别。(查看动画演示)
#include <iostream>
using namespace std;
st();
at();
int main(){
     int i;
     for(i=0;i<5;i++)  cout<<at()<<'/t';
     cout<<endl;
     for(i=0;i<5;i++)  cout<<st()<<'/t';
     cout<<endl;
     return 0;
}
st(){
     static int t=100;             //局部静态变量
     t++;
     return t;
}
at(){
     int t=100;                 //自动变量
     t++;
     return t;
}

3、外部存储类型:用extern说明的变量。

  • 在程序文件中定义的全局变量和函数默认为外部的,其作用域可以延伸到程序的其他文件中。
  • 一个C++程序可以由多个源程序文件组成。多文件程序系统可以通过外部存储类型的变量和函数来共享某些数据和操作。方法是:其他文件如果要使用某个文件中定义的全局变量和函数,应该在使用前用“extern”作外部声明,表示该全局变量或函数不是在本文件中定义的。
  • 外部声明通常放在文件的开头(函数总是省略extern)。
  • 在同一个文件中,如果函数使用到定义在该函数之后的全局变量,也必须对使用到的全局变量进行外部变量声明,以满足先定义后使用的原则。所以,全局变量最好集中定义在文件的起始部分。
  • 外部变量声明不同于全局变量定义。变量定义时,编译器为其分配内存空间,而变量声明则表示该全局变量已在其他地方定义过,编译器不再分配内存空间,直接使用变量定义时所分配的空间。因此,所声明变量的变量名和类型必须与定义的完全相同。

本节重点掌握staticextern这两种类型的使用和区别,区分局部变量和静态局部变量,全局变量和静态全局变量。

标示符的生命期

生命期(Life time)也叫生存期。生命期与存储区域相关,存储区域分为代码区、静态数据区、栈区和堆区,相应地,生命期分为静态生命期、局部生命期和动态生命期。

1、静态生命期 :指的是标识符从程序开始运行时存在,即具有存储空间,到程序运行结束时消亡,即释放存储空间。

  • 具有静态生命期的标识符存放在静态数据区,属于静态存储类型,如全局变量、静态全局变量、静态局部变量。
  • 具有静态生命期的标识符在未被用户初始化的情况下,系统会自动将其初始化为全0
  • 函数驻留在代码区,也具有静态生命期。
  • 所有具有文件作用域的标识符都具有静态生命期

2、局部生命期 :在函数内部或块中定义的标识符具有局部生命期,其生命期开始于执行到该函数或块的标识符声明处,结束于该函数或块的结束处。

  • 具有局部生命期的标识符存放在栈区
  • 具有局部生命期的标识符如果未被初始化,其内容是随机的,不可用
  • 具有局部生命期的标识符必定具有局部作用域;但反之不然,静态局部变量具有局部作用域,但却具有静态生命期。

3、动态生命期

  • 具有动态生命期的标识符由特定的函数调用或运算来创建和释放,如调用malloc()或用new运算符为变量分配存储空间时,变量的生命期开始;而调用free()或用delete运算符释放空间或程序结束时,变量生命期结束。
  • 具有动态生命期的变量存放在堆区。关于new运算和delete运算将在第7章中介绍。