标签:
存储时期即生存周期——变量在内存中保留的时间
变量的作用域和链接一起表明程序的哪些部分可以通过变量名来使用该变量。
注意:生存期和作用域是两个不同的概念。
作用域
作用域描述了程序中可以访问一个标识符的一个或多个区域。一个C变量的作用域可以是代码块作用域、函数原型作用域,或者文件作用域。
在代码块中定义的变量具有代码块作用域,从该变量被定义的地方到包含该定义的代码块的末尾该变量均可见。其次,函数的形式参量尽管在函数的开始花括号前进行定义,同样也具有代码块作用域,隶属于包含函数体的代码块。
传统上,具有代码块作用域的变量都必须在代码块的开始处进行声明。C99放宽了这一规则,允许在一个代码块中任何位置声明变量。一个新的可能是变量声明可以出现在for循环的控制部分,即:
for(int i = 0; i < 10; i++) printf("A C99 feature: i = %d", i);
函数原型作用域适用于函数原型中使用的变量名。函数原型作用域从变量定义处一直到原型声明的末尾。这意味着编译器在处理一个函数原型的参数时,它所关心的只是该参数的类型;您使用设么名字通常是无关紧要的,不需要使它们和在函数定义中使用的变量名保持一致。
一个在所有函数之外定义的变量具有文件作用域。具有文件作用域的变量从它定义处到包含该定义的文件结尾处都是可见的。文件作用域变量也被称为全局变量。
链接
一个C变量具有下列链接之一:
具有代码块作用域或者函数原型作用域的变量有空链接,意味着它们是由其定义所在的代码块或函数原型所私有的。具有文件作用域的变量可能有内部或者外部链接。一个具有外部链接的变量可以在一个多文件程序的任何地方使用。一个具有内部链接的变量可以在一个文件的任何地方使用。
问题:怎样知道一个文件作用域变量具有内部链接还是外部链接?
答:看看在外部定义中是否使用了存储类说明符static,例:
int giants = 5; // 文件作用域,外部链接 static int dodgers = 3; // 文件作用域,内部链接 int main(void) { .... } .....
存储时期
一个C变量有以下两种存储时期之一:静态存储时期和自动存储时期。如果一个变量具有静态存储时期,它在程序执行期间将一直存在。具有文件作用域的变量自动具有静态存储时期。(注意:对于具有文件作用域的变量,关键词static表明链接类型,并非存储时期)。
具有代码块作用域的变量一般情况下具有自动存储时期,但也可创建具有代码块作用域,兼具静态存储时期的局部变量。在程序进入定义这些变量的代码块时,将为这些变量分配内存;当退出这个代码块时,分配的内存将被释放。该思想把自动变量使用的内存视为一个可以重复使用的工作区或者暂存内存。
1° 自动变量
属于自动存储类的变量具有自动存储时期、代码块作用域和空链接。默认情况下,在代码块或函数的头部定义的任意变量都属于自动存储类。然而,也可以显示地使用关键字auto使您的这个意图更清晰。
问题:如果在内层代码块定义了一个具有和外层代码块变量同一名字的变量,将发生什么?
答:在内层代码块定义的名字是内层代码块所使用的变量。我们称之为内层定义覆盖了外部定义,但当运行离开内层代码块时,外部变量重新恢复作用。
除非您显示地初始化自动变量,否则它不会被自动初始化,不要指望这个值是0。
2° 寄存器变量
寄存器变量具有代码块作用域、空链接以及自动存储时期。但是,由于寄存器变量多是存储在一个寄存器而非内存中,所以无法获得寄存器变量的地址。通过使用存储类说明符register可以声明寄存器变量。
3° 具有代码块作用域的静态变量
“静态”一词是指变量的位置固定不动。此类变量和自动变量具有相同的作用域,但当包含这些变量的函数完成工作时,它们并不消失。因为如果一个变量具有静态存储时期,它在程序执行期间将一直存在。即此类变量具有代码块作用域、空链接,却有静态存储时期。从一次函数调用到下一次调用,计算机都记录着它们的值。这样的变量通过使用存储类说明符static在代码块内声明创建。
如果不显示地对静态变量进行初始化,它们将被初始化为0。静态变量和外部变量(?)在程序调入内存时已经就位(即在程序载入内存时,就被载入内存中)。
注意:对函数参量不能使用static,例:
int wontwork(static int flu); // 不允许
4° 具有外部链接的静态变量
具有外部链接的静态变量具有文件作用域、外部链接和静态存储时期。这一类型有时被称为外部存储类,这一类型的变量被称为外部变量。把变量的定义声明放在所有函数之外,即创建了一个外部变量。为了使程序更加清晰,可以在使用外部变量的函数中通过使用extern关键字来再次声明它(但也可以完全省略,它们出现在那里,作用只不过是表明函数使用了这些变量。如果函数中的声明漏掉了extern,就会建立一个独立的自动变量)。如果变量是在别的文件中定义的,使用extern来声明该变量就是必须的。
外部变量的作用域:从声明的位置开始到文件结尾为止。它们也说明了外部变量的生存期。外部变量存在的时间与程序运行时间一样,并且它们不局限于任一函数,在一个特定函数返回时并不消失。
如果您不对外部变量进行初始化,它们将自动被赋初值0。不同于自动变量,只可以用常量表达式来初始化文件作用域变量。
标签:
原文地址:http://www.cnblogs.com/yerenyuan/p/5074179.html