变量的存储类型
在C++语言中,变量通常有4种存储类型,分别为“extern”、“static”、“register”和“auto”。下面逐一进行介绍。
extern存储类型
在介绍extern存储类型之前,先来澄清一个概念——变量的声明和定义。变量的声明是告知编译器变量的名称和数据类型。变量的定义将为变量分配存储区域。通常情况下,变量的声明也被认为是变量的定义。但是可以使用extern关键字只声明而不定义变量。例如:
extern int var;
那么只声明而不定义变量有何好处呢?通常,应用程序可能包含许多文件,如果在一个文件中定义一个全局变量,可能需要在其他文件中进行访问。那么在其他文件中可以使用extern关键字只声明而不定义全局变量,extern关键字将告诉编译器变量的名称和类型,而变量的定义来源于前一个文件。这样就可以在其他文件中共享全局变量了。例如,在一个文件中定义一个整形的全局变量var。
int var = 0 ;
而在另一个文件中通过使用extern关键字声明全局变量var,在该文件中就可以访问全局变量var了。
extern int var;
static存储类型
在介绍static存储类型之前,先来介绍一下局部变量和全局变量。变量按照作用范围的不同可以划分为局部变量和全局变量。局部变量是指在函数内定义的变量,在函数调用结束后,局部变量将消失。而全局变量是指在函数体外定义的变量,它的生命期随着程序的结束而结束。
static存储类型主要是针对局部变量的,如果定义一个静态的局部变量,它的生命期在函数调用结束后会依然存在,在下次调用函数时,会依然保存上一次函数调用结束之后的值。并且,对于静态变量只执行一次初始化(无论函数调用多少次)。
static存储类型表示变量在函数或文件内是“持久性”变量,通常也被称之为静态变量。静态变量分为局部静态变量和全局静态变量。当使用static关键字标识一个局部变量(在函数内部定义的变量)时,该变量将被分派在一个持久的存储区域,当函数调用结束时,变量并不被释放,依然保留其值。当下一次调用函数时,将应用之前的变量值。这一点类似于全局变量,但是与全局变量不同的是,局部静态变量的作用域为当前的函数,它不能被外界函数或文件访问。可以认为局部静态变量是一个在函数调用后保留其值的局部变量。
例如,下面的代码演示了局部静态变量的作用。
void TestStaticVar()
{
static int slocal = 10; //定义一个局部静态变量
printf("%dn",slocal); //输出变量
slocal++; //自加1
}
void main()
{
//连续3次调用TestStaticVar
TestStaticVar();
TestStaticVar();
TestStaticVar();
}
执行上述代码,效果如图1所示。
.jpg)
图1 局部静态变量
上述代码3次调用了TestStaticVar函数,在每次函数调用结束后,局部静态变量slocal都将保留。并且对于局部静态变量只初始化一次,因此每次调用TestStaticVar函数输出的值是不同的。
对于全局静态变量,它的作用域仅限于当前定义的文件,不能够被其他文件使用extern关键字访问。可以认为全局静态变量只是半个全局变量(不能够被其他文件共享)。
register存储类型
在定义变量时,使用register关键字,表示变量将被放置在CPU的寄存器中。与普通变量不同的是,访问register变量要比访问普通变量快很多。register变量只能用于局部变量或作为函数的形式参数,而不能够定义全局的register变量。下面的代码定义了一个register变量。
register int slocal = 10;
对于寄存器变量,程序中不能够获得变量的地址,也不能够成为全局变量或静态变量,但是它可以作为函数的形式参数。
寄存器变量不能够保证将变量放置在寄存器中,也不能保证提高访问速度,它只是对编译器的一个“建议”。如今的编译器都具有优化功能,它会自动地调整变量的放置,因此,在程序中建议避免使用寄存器变量。
auto存储类型
变量的存储方式主要有两种,静态存储和动态存储。全局变量、静态变量均属于静态存储,而普通的局部变量属于动态存储。auto关键字表示变量将被动态存储。默认情况下的局部变量均属于auto变量(也被称为自动变量)。定义一个全局的auto变量的非法的,因为全局变量属于静态存储,与auto变量的相互冲突的。
注意:在定义变量时不能够同时使用register、extern、static和auto4个关键字中的任意两个关键字。因此语句“static register int nData = 10;”的定义是非法的。