作用域和链接描述了标识符的可见性. 存储期描述了通过这些标识符访问的对象的生存期.
C 对象有 4 中存储期: 静态存储期
, 线程存储期
, 自动存储期
, 动态分配存储期
.
如果对象具有静态存储期
, 那么他在程序的执行期间一直存在. 文件作用域变量具有静态存储期. 注意, 对于文件作用域变量, 关键字 static 表明了其链接属性, 而非存储期. 以 static 声明的文件作用域变量具有内部链接. 但是无论是内部链接还是外部链接, 所有的文件作用域变量都具有静态存储期.
线程存储期用于并发程序设计, 程序执行可被分为多个线程. 具有线程存储期的对象, 从被声明时到线程结束一直存在. 以关键字 _Thread_local
声明一个对象时, 每个线程都获得该变量的私有备份.
块作用域的对象通常都具有自动存储期. 当程序进入定义这些变量的块时, 为这些变量分配内存; 当退出这个快时, 释放刚才为变量分配的内存. 这种做法相当于把自动变量占用的内存视为一个可重复使用的工作区或暂存区. 例如, 一个函数调用结束后, 其变量占用的内存可用于存储下一个被调用函数的变量.
变长数组稍有不同, 他们的存储期从声明处到块的末尾, 而不是从块的开始处到块的末尾.
在下面的代码中, 变量 number 和 index 在每次调用 bore()函数时被创建, 在离开时被销毁:
void bore(int number) {
int index;
for ( index = 0 ; index < number ; index ++ ) {
puts("They don't make them the way they used to.\n";
}
}
然而, 块作用域变量也能具有静态存储期. 为了创建这样的变量, 要把变量声明在块中, 且在声明前加上关键字 static:
void more(int number) {
int index;
static int ct = 0;
}
这里, 变量 ct 存储在静态内存中, 他从程序被载入, 到程序结束期间都存在. 但是, 他的作用域定义在more()函数中. 只有在执行该函数时, 程序才能使用 ct 访问他所指定的对象(但是, 该函数可以给其他函数提供该存储区的地址以便间接访问该对象, 例如通过指针形参或返回值).
C 使用作用域, 链接和存储期为变量定义了多种存储方案.
5 中存储类别:
存储类别 | 存储期 | 作用域 | 链接 | 声明方式 |
---|---|---|---|---|
自动 | 自动 | 块 | 无 | 块内 |
寄存器 | 自动 | 块 | 无 | 块内, 使用关键字 register |
静态外部链接 | 静态 | 文件 | 外部 | 所有函数外 |
静态内部链接 | 静态 | 文件 | 内部 | 所有函数外, 使用关键字 static |
静态无连接 | 静态 | 块 | 无 | 块内, 使用关键字 static |
网友评论