C++主要有三种存储类型:
- 自动存储类型:在函数定义中声明的变量(包括函数参数),他们在函数执行时被创建,在函数执行完毕后被释放。
- 静态存储类型:在函数定义外定义的变量和使用关键字static定义的变量,它们在程序运行的整个过程中都存在。
- 动态存储类型:用new运算符分配的内存将一直存在,知道delete将其释放或程序结束为止。
从存储区域来看,三种类型分布如下:
简而言之:自动存储类型保存在栈,静态存储类型保存在BSS段及数据段,动态存储类型保存在堆区。
自动存储类型
自动存储类型比较简单,这里不再做过多介绍。
静态存储类型
静态存储类型其重点主要在于其链接性,静态存储类型的链接性主要分为三种:外部链接性、内部链接性、无连接性。这三种链接的区别在于:
- 外部链接性:可在其他文件中访问。
- 内部链接性:只能在当前文件中访问。
- 无链接性:只能在当前函数或代码中访问。
外部链接性
如果要声明一个具有外部链接性的静态存储类型,我们需要在函数外定义它们,在定义之后,我们可以在任何函数中使用它,因此该类型也叫全局变量。
对于全局变量,必须确保只有一次定义,如果要引用它则需进行引用声明,引用声明通过extern关键字完成,需要注意的是:引用声明不能进行初始化,否则引用声明变成了定义。实例如下:
double up; //定义
extern int blem; //引用声明
extern int n = 0;//定义
对于全局变量定义而言,可以初始化也可以不初始化,但是从严谨性考虑,还是建议进行初始化。
使用全局变量时,我们难免会碰到局部变量隐藏了全局变量,当局部变量与全局变量命名相同时,就会发生,那么怎么区别二者呢?C++中提供了::,当使用::时,即表示使用了全局变量,示例如下:
int warn = 1;
void local()
{
double warn = 0.5;
cout << "global :" << ::local << endl;
cout << "local :" << warn << endl;
}
除了以上要点之外,使用全局变量还要注意以下几点:
- 不要在头文件中声明全局变量,一旦头文件被多个文件包含,那么将会出现重定义错误。
- 全局变量虽然好用,但是如果用于多线程,需要考虑资源互斥问题。
内部链接性
使用static可以声明一个具有内部链接性的静态存储变量,静态存储变量也在函数外部声明,其与全局变量的唯一区别在于其多了一个关键字static。
链接性为内部的变量只能在所属的文件中使用,同时由于不存在外部链接性,所以它支持在多个文件中声明同一名称的变量,甚至可以将其定义在头文件中,而不用担心编译过程中报错。
这里需要注意的是,除了static可以定义一个内部链接性的静态存储变量,全局const声明的链接性也是内部的,这主要是考虑到这种类型不太需要外部链接性(毕竟全局变量的作用主要在于其可读可写),但是这并不意味着我们完全失去了在多个文件中共享同一const全局变量的机会,我们可以像下面这样写:
extern const int finer = 10; //声明
extern const int finer; //引用声明,这里不能初始化
通过为const全局变量声明前面增加extern,该变量也具有了外部链接性。
无链接性
当在函数内部创意一个static变量时,该变量是没有链接性的,这种变量的特点在于:即使函数已经结束,但变量仍然存在。这也导致:两次函数调用之间,静态局部变量的值是一直不变的。
动态存储类型
动态存储类型是通过new分配的内存,需要程序员自己去管理与释放,否则就会出现内存泄漏。