概要
持续性:指变量保留在内存的时间,分为自动存储、静态存储和动态存储;
1.自动存储持续性:C++有两种存储持续性为自动的变量,一种是局部变量,定义在函数内部或代码块内部的变量,其作用域限定在函数内部或代码块内部,函数或代码块执行完毕后自动销毁。另一种是函数参数,定义在函数参数列表中的变量,其作用域限定在函数内部,函数执行完毕后自动销毁。
2.静态存储持续性:在函数定义和代码块内部之外定义的变量或用static定义的变量,他们存储在静态存储空间,它们在程序运行完才被释放;
3.动态存储持续性:用new关键字分配的空间,直到delete或程序结束,内存才被释放;
作用域:指变量在单文件中能够调用的范围,分为代码块和整个文件;
链接性:指变量在文件之间能够调用的范围,外部链接性可以在文件之间共享,内部链接性可以在文件内部的函数间共享,无链接性没有共享性;
自动存储持续性变量的作用域和链接性
在函数中声明的参数和变量的持续性为自动,它们的作用域为局部,链接性为无
静态存储持续性变量的作用域和链接性
静态变量分为以下三种,下面分别介绍。
静态存储、无链接性
将局部变量用static修饰时,变量将具有静态持续性、无链接性和作用域为代码块;
静态持续性意味着它始终占据一块内存,当重复运行一段代码时,它只初始化一次;
void func()
{
static int i = 0;
cout << i;
i++;
}
int main()
{
for (int i = 0; i < 5; i++)
{
func();//输出01234
}
return 0;
}
而又由于是局部变量,因此它链接性为无,作用域为代码块。
静态存储、外部链接性
定义在函数外部的变量为外部变量,它具有外部链接性,持续性为静态;
int i = 1;//持续性为静态、链接性为外部
int main()
{
return 0;
}
在其他源文件去使用外部变量时,需要用到extern关键字,规则是外部变量只需要在某一个文件里定义一次,但是在其他文件去使用它时,需要先声明,声明的时候要带上extern;
//A.cpp文件
int i = 1
//B.cpp文件
extern int i;//声明时不能初始化
int main()
{
cout<<i;
return 0;
}
一般来讲,extern变量声明一般包含在头文件,因此上述代码可写成
//A.h文件
extern int i;
//A.cpp文件
int i = 1
//B.cpp文件
#include"A.h"
int main()
{
cout<<i;
return 0;
}
静态存储、内部链接性
指用static修饰作用域为单个文件的变量
static int i = 0;
int main()
{
return 0;
}
如果说我想定义一个本文件内部所有函数都能使用的一个全局变量,但又担心命名与那种所有文件都能访问的全局变量冲突,那就需要用static修饰;
用const修饰的变量作为常量具有内部链接性,一般包含在头文件,因此每个用到该常量的文件都需要包含该头文件。
动态存储持续性变量
用new分配内存的动态变量不参与链接性、作用域的讨论,因为它只与delete的时机有关。
小结
C++的存储方案决定了变量保留在内存中的时间(储存持续性)以及程序的哪一部分可以访问它(作用域和链接性)。
自动变量是在代码块(如函数体或函数体中的代码块)中定义的变量,仅当程序执行到包含定义的代码块时,它们才存在,并且可见。自动变量可以通过使用存储类型说明符register或根本不使用说明符来声明,没有使用说明符时,变量将默认为自动的。register说明符提示编译器,该变量的使用频率很高,但C++11摒弃了这种用法。
静态变量在整个程序执行期间都存在。对于在函数外面定义的变量,其所属文件中位于该变量的定义后面的所有函数都可以使用它(文件作用域),并可在程序的其他文件中使用(外部链接性)。另一个文件要使用这种变量,必须使用extern关键字来声明它。对于文件间共享的变量,应在一个文件中包含其定义声明(无需使用extern,但如果同时进行初始化,也可使用它),并在其他文件中包含引用声明(使用extern且不初始化)。在函数的外面使用关键字static定义的变量的作用域为整个文件,但是不能用于其他文件(内部链接性)。在代码块中使用关键字static定义的变量被限制在该代码块内(局部作用域、无链接性),但在整个程序执行期间,它都一直存在并且保持原值。
动态内存分配和释放是使用new和delete进行的,它使用自由存储区或堆来存储数据。调用new占用内存,而调用delete释放内存。程序使用指针来跟踪这些内存单元。