资料摘自《C++ Primer Plus》
存储持续性
1自动存储持续性:在函数定义中声明的变量(包括函数参数)的存储持续性为自动的。它们在程序开始执行其所属的函数或代码块时被创建,在执行完函数或代码块时,它们使用的内存被释放。
2静态存储持续性:在函数定义外定义的变量和使用关键字static定义的变量的存储持续性都为静态。(请注意)它们在整个运行过程中都存在。
3线程存储持续性(C++11):当前,多核处理器很常见,这些CPU可同时处理多个执行任务。这让程序能够将计算放在可并行处理的不同线程中。如果变量是使用关键字thread_local声明的,则其生命周期与所属的线程一样长。
4动态存储持续性:用new运算符分配的内存将一直存在,直到使用delete运算符将其释放或程序结束为止。这种内存的存储持续性为动态,有时被称为自由存储(free store)或堆(heap)。
作用域和链接性
作用域(scope)描述了名称在文件的多大范围内可见。例如,函数中定义的变量可在该函数中使用,但不能在其他函数中使用;而在文件中的函数定义之前定义的变量则可在所有函数中使用。
链接性(linkage)描述了名称如何在不同单元间共享。链接性为外部的名称可在文件间共享,链接性为内部的名称只能由一个文件中的函数共享,自动变量的名称没有链接性,因为它们不能共享。
默认情况下,在函数中声明的函数参数和变量的存储持续性为自动,作用域为局部,没有链接性。
静态存储持续性变量提供了3种链接性:外部链接性(可在其他文件中访问)、内部链接性(只能在当前文件中访问)和无链接性(只能在当前函数或代码块中访问)。这3种链接性都在整个程序执行期间存在,与自动变量相比,它们的寿命更长。由于静态变量的数目在程序运行期间是不变的,因此程序不需要使用特殊的装置(如栈)来管理它们。编译器将分配固定的内存块来存储所有的静态变量,这些变量在整个程序执行期间一直存在。如果没有显式地初始化静态变量,编译器将把它设置为0。默认情况下,静态数组和结构将每个元素成员的所有位都设置为0。
下面列出5种变量存储方式
存储描述 | 持续性 | 作用域 | 链接性 | 如何声明 |
---|---|---|---|---|
1 自动 | 自动 | 代码块 | 无 | 在代码块中 |
2 寄存器 | 自动 | 代码块 | 无 | 在代码块中,使用关键字register |
3 静态,无链接性 | 静态 | 代码块 | 无 | 在代码块中,使用关键字static |
4 静态,外部链接性 | 静态 | 文件 | 外部 | 不在任何函数内 |
5 静态,内部链接性 | 静态 | 文件 | 内部 | 不在任何函数内,使用关键字static |
示例说明:
//file1.cpp
extern int cats = 20; //属于第4种存储方式(下面为了方便直接写上第几种)
int dogs = 22; //第4种
int fleas; //第4种(默认设置值为0)
static int errors = 5; //第5种
void f1(int n) { //参数n属于第1种
int m; //第1种
static int si = 5; //第3种
static int sii; //第3种(默认设置值为0)
...
}
...
//file2.cpp
//下面使用的cats,dogs,fleas都来自file1.cpp
extern int cats;
extern int dogs;
extern int fleas;
static int errors = 2; //第5种(虽然在file1.cpp中也定义了同名称的静态变量,但它只能在当前文件中访问,所有两者不冲突,它们是不同的两个变量)
void f2(int n) {
int m; //第1种
static int si = 5; //第3种(虽然在file1.cpp中也定义了同名称的静态变量,但它只能在当前代码块中访问,所有两者不冲突,它们是不同的两个变量)
static int sii; //第3种
...
}
...
//file3.cpp
//下面是错误的示范
//单定义规则(One Definition Rule,ODR):该规则指出,变量只能有一次定义。
int dogs = 3; //第4种,但这是错误的,因为它违反了单定义规则,这里它试图创建另一个同名的外部变量
...