C 为变量提供了5种不同的存储模型,或称为存储类。可以按照一个变量的存储时期描述他,也可以按照它的作用域以及它的链接来描述他。存储时期就是变量在内存中保留的时间,变量的作用域和链接一起表明程序的哪些部分可以通过变量名来使用该变量。不同的存储类提供了变量的作用域、链接以及存储时期的不同组合。
作用域
作用域描述了程序中可以访问一个标识符的一个或多个区域。一个C变量的作用域可以是代码块作用域、函数原型作用域,或者文件作用域。在代码块中定义的变量具有代码块作用域,从该变量被定义的地方到包含该定义的代码块的末尾该变量均可见。另外,函数的形参尽管在函数的开始花括号前进行定义,同样也具有代码块作用域。
函数原型作用域从变量定义处一直到原型声明的末尾。这意味着编译器在处理一个函数原型的参数时,它所关心的只是该参数的类型。
一个在所有函数之外定义的变量具有文件作用域。具有文件作用域的变量从它定义处到包含该定义的文件结尾处都是可见的。
链接
一个C变量具有下列链接之一:外部链接(external linkage),内部链接(internal linkage),或空链接(no linkage)。具有代码块作用域或者函数原型作用域的变量有空链接,意味着他们是由其定义所在的代码块或函数原型所私有的。具有文件作用域的变量可能有内部或者外部链接。一个具有外部链接的变量可以在一个多文件程序的任何地方使用。一个具有内部链接的变量可以在一个文件的任何地方使用。
那么怎样知道一个文件作用域变量具有内部链接还是外部链接?你可以看看在外部定义中是否使用了存储类说明符 static:
int giants = 5; // 文件作用域,外部链接
static int dodgers = 3; // 文件作用域,内部链接
int main() {
...
}
存储时期
一个C变量有以下两种存储时期之一:静态存储时期(static storage duration)和自动存储时期(automatic stoage duration)。如果要给变量具有静态存储时期,它在程序执行期间将一直存在。具有文件作用域的变量具有静态存储时期。注意对于具有文件作用域的变量,关键字 static 表明链接类型,并非存储时期。一个使用 static 声明了的文件作用域变量具有内部链接,而所有的文件作用域变量,无论它具有内部链接,还是具有外部链接,都具有静态存储时期。
具有代码块作用域的变量一般情况下具有自动存储时期。在程序进入定义这些变量的代码块时,将为这些变量分配内存:当退出这个代码块时,分配的内存将被释放。该思想吧自动变量使用的内存视为一个可以重复使用的工作区或者暂存内存。例如,在一个函数调用结束后,它的变量所占用的内存可被用来存储下一个被调用函数的变量。
C使用作用域,链接和存储时期来定义5种存储类:自动、寄存器、具有代码块作用域的静态、具有外部链接的静态,以及具有内部链接的静态。下表列出了这些组合:
存储类 | 时期 | 作用域 | 链接 | 声明方式 |
---|---|---|---|---|
自动 | 自动 | 代码块 | 空 | 代码块内 |
寄存器 | 自动 | 代码块 | 空 | 代码块内,使用关键字 register |
具有外部链接的静态 | 静态 | 文件 | 外部 | 所有函数之外 |
具有内部链接的静态 | 静态 | 文件 | 内部 | 所有函数之外,使用关键字 static |
空链接的静态 | 静态 | 代码块 | 空 | 代码块内,使用关键字 static |
网友评论