C++笔记(19)——存储的持续性、作用域和链接性

1、定义

作用域(scope): 描述了名称在文件的多大范围内可见。如:函数中定义的变量只在该函数中使用;文件中函数之前定义的变量可以在所有的函数中使用。函数原型作用域中使用的名称只能在包含参数列表的括号内使用。

链接性(linkage):描述了名称如何在不同单元之间共享。链接性为外部链接的可以在文件间共享;为内部链接的可以在文件内的函数共享;没有链接性的不能共享。

2、自动存储变量

在函数中声明的函数参数和变量的存储持续性为自动,作用域为局部,没有链接性。在代码块(花括号括起来的)定义的变量作用域和存在时间只存在于代码块。代码块或者函数执行完毕,自动存储变量将被释放。对自动存储变量,新的定义隐藏以前的定义,比如在函数中,一个代码块中定义的变量与函数中的变量重复,则在该代码块中使用新变量,代码块执行结束,则使用原来的变量。自动变量存在栈中,即LIFO(陷入后出)。

3、静态存储变量

静态存储变量按连接性分为三种:(1)外部链接性(文件间共享),在代码块(包括函数以及主函数)外声明;(2)内部链接性(文件*享),在代码块外声明,并加static限定符;(3)没有链接性(不共享),在代码块内声明,并加static限定符。一般,编译器分配固定的内存块存储所有的静态变量,这些静态变量在整个程序执行期间都存在,且默认值为零。

C++笔记(19)——存储的持续性、作用域和链接性

(1)外部链接性(全局变量)

必须定义在函数外,只能定义一次。可以在main函数前面,也可以放在头文件中,但在头文件总能一般要放在#ifndef.......#endif之间,避免多个源文件包含该头文件时多次定义而报错。一个文件中定义的全局变量,另一个文件在使用前需要利用extern进行引用声明。同理,函数也是外部链接性,一个文件中定义的函数,另一个文件在使用前进行引用声明即可,但函数可以省略extern,函数可以将原型放在头文件中,定义一般不放在头文件中(内联函数可以放在头文件中)(也可以在函数定义和函数原型前均加static限定词,将其外部链接性变为内部链接性)。

C++笔记(19)——存储的持续性、作用域和链接性

(2)内部链接性

在函数外定义,前面加上static限定符。不同的文件中内部链接性的静态变量可以重复,也可定义在头文件中,不同的源文件包含头文件时将定义不同的内部静态变量。当内部静态变量和外部静态变量(即全局的外部链接静态变量)同时出现时,内部静态变量优先,也可在变量前加作用域解析运算符::来表示使用变量的全局版本。

当在主函数中调用其他源文件中的函数时,函数在执行时首先考虑函数定义所在文件中的变量而不是主函数所在文件中的变量。

(3)无链接性

这种变量只在代码块中可用,但是代码块不执行时,改变了不消失,再次使用时变量的值不重置。

4、说明符和限定符

(1)限定符

const:内存被初始化后,程序不再对进行修改;

volatile:程序代码没有对内存单元进行修改,其值也可能变化,一般与硬件相互配合,通过硬件对该单元值进行改变。

mutable:即使const限定不能修改,也可能被修改。比如,结构声明时,结构成员前加mutable时,当结构被限定为const时,加了mutable的成员仍可修改。

(2)const的其他作用

const加在全局变量前,将全局变量变为局部常量,即值不再修改,链接性从外部变为内部。但可以通过extern的作用再将其改为外部链接性。

5、动态分配

new的两种用法:常规用法;定位运算符(#include <new>)。

C++笔记(19)——存储的持续性、作用域和链接性

(1)常规用法

内存的分配和释放由new和delete管理,不受链接性和作用域限制。但是,分配的内存指针收到作用域和链接性限制。可以将指针定义为外部链接变量,其他文件也可以使用该内存,使用前如下形式声明:

extern float * p;

(2)定位运算符

不能使用delete