文章目录
0. 前言
程序员可以通过C的内存管理系统指定变量的作用域和声明周期,实现对程序的控制。
合理使用内存存储数据是程序设计的一个要点
1. 存储类别
关键概念:
- 对象(object):从硬件方面看,被储存的每个值都占用一定的物理内存,C语言把这样的一块内存称为对象
- 可以用 存储期(storage duration) 描述对象。所谓存储期是指对象在内存中保留了多长时间
- 标识符用来访问对象,可以用作用域(scope)和连接(linkage)描述标识符,标识符的作用域和连接表明了程序的哪些部分可以使用它
对象可以存储一个或多个值。
一个对象可能并未储存实际的值,但是它在储存适当的值时一定具有相应的大小
说明:
- 面向对象编程中的对象指的是类对象,其定义包括数据和允许数据进行的操作
1.1 作用域
作用域描述程序中可访问标识符的区域。一个C变量的作用域可以是块作用域、函数作用域、函数原型作用域或文件作用域
1.1.1 块作用域
块是用一对花括号括起来的代码区域
定义在块中的变量具有块作用域(block scope)
块作用域的可见范围是从定义处到包含该定义的块的末尾。
虽然函数的形参,声明在函数的左花括号之前,但是它们也具有块作用域,属于函数体这个块
声明在内层块中的变量,其作用域仅局限于该声明所在的块
1.1.2 函数作用域(function scope)
1.1.3 函数原型作用域(function protoype scope)
函数原型作用域用于函数原型中的形参名(变量名)
函数原型作用域的范围是从形参定义处到原型声明结束
意味着,编译器在处理函数原型中的形参时只关心其类型,而形参名无关紧要。即使有形参名,也不必于函数定义中的形参名相匹配
注意:
- 在变长数组中,函数声明中的形参名有用
void use_a_VLA(int n,int m, arr[n][m]);
上述代码方括号中必须使用在函数原型中已声明的名称
1.1.4 文件作用域(file scope)
定义在函数外名的变量具有文件作用域
通常源代码(.c文件)中包好一个或多个头文件(.h扩展名)。头文件会一次包含其它文件,所以包含多个单独的物理文件。但是C预处理实际上用包含的头文件替换#include指令。所以编译器源代码文件和所有的头文件都看成是一个包含信息的单独文件。这个文件被称为翻译单元(translation unit)
描述一个具有文件作用域的变量时,它的实际可见范围是整个翻译单元。
1.2 链接
C变量有3种链接属性:外部链接、内部链接或无链接
具有块作用域、函数作用域或函数原型作用域的变量都是无链接变量
具有文件作用域的变量可以是外部链接或内部链接。
外部链接变量可以在多个文件程序中使用,内部链接变量只能在一个翻译单元中使用
内部链接的文件作用域 简称文件作用域
外部链接的文件作用域 简称全局作用域或程序作用域
区分文件作用域是内部链接还是外部链接的方式:----static
int giants=5; //文件作用域,外部链接
static int dodgers=3; //文件作用域,内部链接
程序说明:
giants 变量可以在多个翻译单元中使用,而dodgers变量只能在本翻译单元中使用
1.3 存储期(变量生存周期)
作用域和链接描述了标识符的可见性。
存储期描述了通过通过这些标识符的对象的生存期
C语言有四种存储期:
静态存储期、线程存储期、自动存储期、动态分配存储期
1.3.1 静态存储期:
如果对象具有静态存储期,那么他在程序的执行期间一直存在。
文件作用域变量具有静态存储期
1.3.2 线程存储期:
1.3.3 自动存储期
块作用域通常具有自动存储期。当程序进入定义这些变量的块时,为这些变量分配内存;当退出这些块时,释放刚才为变量分配的内存。
对于定义在块作用