什么是静态存储,动态存储
静态存储变量通常是在变量定义时就分定存储单元并一直保持不变, 直至整个程序结束。
动态存储变量是在程序执行过程中,使用它时才分配存储单元, 使用完毕立即释放。
典型的例子是函数的形式参数,在函数定义时并不给形参分配存储单元,只是在函数被调用时,才予以分配,
调用函数完毕立即释放。如果一个函数被多次调用,则反复地分配、 释放形参变量的存储单元。
从以上分析可知, 静态存储变量是一直存在的, 而动态存储变量则时而存在时而消失。
我们又把这种由于变量存储方式不同而产生的特性称变量的生存期。 生存期表示了变量存在的时间。
生存期和作用域是从时间和空间这两个不同的角度来描述变量的特性,这两者既有联系,又有区别。
一个变量究竟属于哪一种存储方式, 并不能仅从其作用域来判断,还应有明确的存储类型说明。
四种变量的存储方式和作用域
在C语言中,有以下四种变量:静态变量(static)、自动变量(auto)、寄存器变量(register)、外部变量(extern)。
其中自动变量和寄存器变量属于动态存储方式,外部变量和静态局部变量属于静态存储方式。
下面我们详细介绍这四种变量:
一、静态局部变量-静态存储
定义格式:
static 数据类型 变量名;
存储特点:
静态局部变量属于静态存储。
在程序执行过程中,即使所在函数调用结束也不释放。
换句话说,在程序执行期间,静态局部变量始终存在,但其它函数是不能引用它们的。
初始化:
定义但不初始化,则自动赋以"0"(整型和实型)或' '(字符型);
且每次调用它们所在的函数时,不再重新赋初值,只是保留上次调用结束时的值!
使用场合:
需要保留函数上一次调用结束时的值。
变量只被引用而不改变其值。
二、自动变量-动态存储
定义格式:
[auto] 数据类型 变量名;
存储特点:
自动变量属于动态存储方式。
在函数或复合语句中定义的自动变量,只在该函数复合语句内有效;函数复合语句被调用时分配存储空间,调用结束就释放。
初始化:
定义而不初始化,则其值是不确定的。
如果初始化,则赋初值操作是在调用时进行的,且每次调用都要重新赋一次初值。
由于自动变量的作用域和生存期,都局限于定义它的个体内(函数或复合语句),
因此不同的个体中允许使用同名的变量而不会混淆。
即使在函数内定义的自动变量,也可与该函数内部的复合语句中定义的自动变量同名。
建议:系统不会混淆,并不意味着人也不会混淆,所以尽量少用同名自动变量!
自动变量与静态局部变量的示例如下:
void auto_static() { int var_auto=0; /*自动变量:每次调用都重新初始化*/ static int var_static=0; /*静态局部变量:只初始化1次*/ printf(“var_auto=%d, var_static=%d ”, var_auto, var_static); ++var_auto; ++var_static; } void main() { int i; for(i=0; i<5; i++) auto_static(); }
输出结果:
三、寄存器变量-动态存储
存储特点:
一般情况下,变量的值都是存储在内存中的。
为提高执行效率,C语言允许将局部变量的值存放到寄存器中,这种变量就称为寄存器变量。
定义格式:
register 数据类型 变量名;
寄存器变量需要注意以下几点:
1)只有局部变量才能定义成寄存器变量,即全局变量不行。
2)对寄存器变量的实际处理,随系统而异。例如,微机上的MSC和TC 将寄存器变量实际当作自动变量处理。
3)允许使用的寄存器数目是有限的,不能定义任意多个寄存器变量。
四、外部变量-静态存储
存储特点:
外部变量属于静态存储方式。又分为静态外部变量和非静态外部变量
静态外部变量
只允许被本源文件中的函数引用
定义格式: static 数据类型 外部变量名;
非静态外部变量
允许被其它源文件中的函数引用
定义时缺省static关键字的外部变量,即为非静态外部变量。
定义格式:数据类型 外部变量名;
其它源文件中的函数,引用非静态外部变量时,需要在引用函数所在的源文件中进行说明:
格式:extern 数据类型 外部变量表;
静态局部变量和静态外部变量同属静态存储方式,但两者区别较大:
1)定义的位置不同。
静态局部变量在函数内定义,静态外部变量在函数外定义。
2)作用域不同。
静态局部变量属于内部变量,其作用域仅限于定义它的函数内;
虽然生存期为整个源程序,但其它函数是不能使用它的。
静态外部变量在函数外定义,其作用域为定义它的源文件内;
生存期为整个源程序,但其它源文件中的函数也是不能使用它的。
3)初始化处理不同。
静态局部变量,仅在第1次调用它所在的函数时被初始化,
当再次调用定义它的函数时,不再初始化,而是保留上1次调用结束时的值。
而静态外部变量是在函数外定义的,不存在静态内部变量的“重复”初始化问题,
其当前值由最近1次给它赋值的操作决定。
把局部变量改变为静态内部变量后,改变了它的存储方式,即改变了它的生存期。
把外部变量改变为静态外部变量后,改变了它的作用域,限制了它的使用范围。
因此,关键字“static”在不同的地方所起的作用是不同的。