一、自动存储持续性
默认情况下,在函数内部声明的函数参数和变量的存储持续性为自动的,作用域为局部,没有链接性。也就是说自动变量只在包含它的函数或代码块内部可见。
int main()
{
int t = 5;
{
cout << "Hello\n";
int w = -2;
cout << w << " " << t << endl;
}
cout << t << endl;
}
上述代码中,w变量包含在代码块当中,只有在执行到该代码块时w才被分配内存,代码块执行结束后,w的内存释放。
二、静态持续变量
1、C++为静态持续性变量提供了3种链接性:
(1)外部链接性:可在其他文件中访问,需要在代码块外面声明;
(2)内部链接性:只能在当前文件中访问,需要在代码块外声明,并且使用static限定符;
(3)无链接性:只能在当前函数或代码块中访问,需要在代码块内声明,并且使用static限定符;
2、静态持续性变量的初始化:
(1)零初始化:未被初始化的静态变量的所有位呗设置为0,称为零初始化
(2)常量表达式初始化
(3)动态初始化
其中零初始化和常量表达式初始化统称为静态初始化
例如:
#include"cmath"
int x;//zero initialization
int y=5;//const-expression initialization
int z=2*sizeof(long)+1;//const-expression initialization
const double pi=4.0*atan(1.0);//dynamic initialization
3、静态持续性、外部链接性
链接性为外部的变量称为外部变量(全局变量),其存储持续性为静态,作用域为整个文件。
(1)单定义规则(ODR)
一方面,每个使用外部变量的文件中都必须声明它,另一方面每个变量只能定义一次。为此C++提供了两种声明的方式:
定义声明(简称定义):给变量分配内存空间
引用声明(简称声明):不给变量分配存储空间,因为它引用已有变量
引用声明使用关键字extern,且不进行初始化;否则声明为定义,导致分配存储空间。
double x;//definition,x is 0
extern int y;// y defined elsewhere
extern int z=10;//definition because initialized
如果要在多个文件使用外部变量,只需要在一个文件中包含该变量的定义,但在使用该变量的文件里使用关键字extern来声明它。例如
//file0.cpp
extern int cats=20;//definition
int dogs=22;//definition
int fleas;//definition
//file1.cpp
extern int cats;//not definition because they use
//file2.cpp
extern int cats;
(2)定义与全局变量同名的局部变量后,局部变量将屏蔽全局变量。为了防止屏蔽,可以使用作用域解析运算符(::),放在变量名前面,表示使用全局变量的版本。
4、静态持续性、内部链接性
将static限定符用于作用域为整个文件的变量时,该变量的链接性为内部的,这说明该变量只能在当前文件中使用。但常规外部变量都具有外部链接性,即可以在其他文件中使用。
//file1
int error=20;//external declaration
//file2
int error=5;
上述程序会出现问题,因为它违反了单定义规则。file2中的定义试图创建一个外部变量,因此程序将包含error的两个定义。
如果文件定义一个静态外部变量,其名称与另一个文件中声明的全局变量相同,在该文件中静态变量将隐藏常规外部变量。
//file1
int error=20;//external declaration
//file2
static int error=5;
综上所述,可以使用外部变量在多个文件当中共享数据;可使用链接性为内部的静态变量在同一个文件的不同函数之间共享数据。
5、静态存储持续性、无链接性
将static用于代码块中定义的变量。该变量只在该代码块中可用,但在代码块外面也存在。因此函数在两次调用之间,静态局部变量的值不改变。