变量的存储类型
存储类型决定变量在内存中的存储位置。在计算机的内存和CPU的寄存器都可以存储变量。
C语言中变量的存储类型分为自动型(auto)、寄存器型(register)、外部型(extern)、和静态型(static)四种。
变量的存储方式分为两大类,即静态存储和动态存储。
静态存储
在编译时由系统分配固定的存储空间,直到程序运行结束后才释放所占用的存储空间
动态存储
在程序运行时根据需要动态地分配和释放存储空间。
注:自动型变量和寄存器型变量属于动态存储;外部变量和静态变量属于动态存储。
变量的生存期
由于必须为定义的变量分配内存单元(或寄存器),所以变量有存活时间的问题,从系统为变量分配内存单元(或寄存器)开始到系统收回内存单元(或寄存器)的期间称为“变量的生存期”。在变量的生存期以外使用该变量会导致编译错误。
变量作用域
变量有效的范围称为变量的作用域。C语言中所有的变量都有其作用域。变量说明的位置不同,其作用域也不同。
用户使用的存储空间分为程序区、静态存储区和动态存储区三部分。程序区存放源代码,静态存储区和动态存储区存放数据。
全局变量和局部变量
根据变量生存期的不同,变量可分为局部变量和全局变量。
生存期覆盖了定义点到整个程序结束的变量称为全局变量
;生存只覆盖了某个函数(或复合语句)的变量称为局部变量
。
全局变量存放在静态存储区,属于静态存储方式。在整个程序运行期间,全局变量始终占用固定的存储单元,直到程序运行结束才释放。全局变量的生存期与程序运行期相同。定义全局变量时如果没有初始化,则自动赋值0或'\0'。用于说明全局变量的存储类型的关键字是 extern 和 static。
1、用extern 在一个文件内扩展全局变量的作用域。全局变量的作用域是从它的定义处开始到本程序文件末尾。用extern声明变量时,变量的数据类型可以写也可以不写。
2、可以用 static 将全局变量的作用域限制在本文件。
3、对于局部变量而言,声明存储类型的作用是指定变量的存储位置(静态存储区或动态存储区)和生存期;对于全局变量而言,声明存储类型的作用是扩展或限制变量的作用域。
内部变量和外部变量
主函数中定义的内部变量,只能在主函数中使用,其他函数不能使用。同时,主函数中也不能使用其他函数定义的内部变量。因为主函数也是一个函数,与其他函数是平行的关系。这一点与其他高级语言不同,应予以注意。
在函数外部定义的变量称为“外部变量”。外部变量不属于任何一个函数,其作用域是从定义外部变量的位置开始到本源程序文件结束。外部变量可被作用域内的函数直接使用。
//a 已经在其他文件定义过了
extern int a;
外部变量的定义,必须在所有的函数之外,且只能定义一次。而外部变量的声明,出现在需要使用该全局变量的函数内,而且可以出现多次。
变量的生存期和作用域
1、外部变量只能定义为无存储类型或静态类型(static),不能定义为自动型(auto)或寄存器型(register)。内部变量可以定义为自动型、寄存器型和静态型
。
2、外部变量都全局变量。
3、声明为auto或register类型的内部变量是局部变量,只在所定义的函数或复合语句中存活。
4、声明为static存储类型的内部变量是全局变量,在整个程序运行期间都不释放。其作用域只是所定义的函数或复合语句。
5、声明为auto和register存储类型的内部变量在不同的函数或复合语句中可以重名,因为离开了所定义的函数或复合语句则释放变量,重名的变量不会发生冲突;声明为static存储类型的内部变量在不同的函数或复合语句中也可以重名,因为其作用域是所定义的函数或复合语句内部,不会发生冲突。
全局外部变量可以加强函数之间的数据联系,但又使函数依赖于这些外部变量,因而使得函数的独立性降低。从模块化程序设计的观点而言破坏了模块的独立性,在模块(函数)中无法确定某些全局外部变量的变化,必须在模块(函数)之外寻找,使程序可读性差,因此不是非用不可时,不建议使用全局外部变量。