词条 | 静态变量 |
释义 | § 百科名片 静态变量的类型说明符是static。 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量, 例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。 对于自动变量,它属于动态存储方式。 但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式。 由此看来,一个变量可由static进行再说明,并改变其原有的存储方式。静态变量 § 静态局部变量定义 在局部变量的说明前再加上static说明符就构成静态局部变量。 静态变量 例如: static int a,b; static float array[5]={1,2,3,4,5}; § 静态局部变量特点 静态局部变量属于静态存储方式,它具有以下特点: (1)静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。 (2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。 (3)允许对构造类静态局部量赋初值。若未赋以初值,则由系统自动赋以0值。 (4)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点, 可以看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。 给读者一个简单直白的例子(区别静态局部变量和动态局部变量): int fun(int n) { static int f=1; /*请注意这行的修改*/ 这是 static 结果: f=f*n; return(f); } int main() { int i; for(i=1;i<=5;i++) printf("%d!=%d\",i,fun(i)); } ========================================================= int fun(int n) { int f=1; /*请注意这行的修改*/ 结果是: f=f*n; return(f); } int main() { int i; for(i=1;i<=5;i++) printf("%d!=%d\",i,fun(i)); } ——————————————————————————————————————————————— Module Module1 Public a As Integer ‘未赋值的情况下a的值是0 End Module Public Class Form1 Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load a += 1 End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click a += 1 MsgBox(a) ’结果是2(0+1+1)因为是a是模块级静态全局变量,所以按按钮3以后,直到关闭程序a的值都会是2 End Sub End Class § 静态全局变量定义 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。应予以注意。 § 静态变量与自动变量与内存的关系 1.分配给全局变量的内存,一直到程序运行结束时才释放。 2.对于在程序块中申明的变量,在块的入口处对其分配内存,在块退出时释放内存,则这种变量为自动变量。一直到程序结束时才释放内存的称为全局变量。 静态变量的存活期,除范围之外,变量还有存活期,在这一期间变量能够保持它们的值。在应用程序的存活期内一直保持模块级变量和公用变量的值。但是,对于 Dim 声明的局部变量以及声明局部变量的过程,仅当过程在执行时这些局部变量才存在。通常,当一个过程执行完毕,它的局部变量的值就已经不存在,而且变量所占据的内存也被释放。当下一次执行该过程时,它的所有局部变量将重新初始化。 但可将局部变量定义成静态的,从而保留变量的值。在过程内部用 Static 关键字声明一个或多个变量,其用法和 Dim 语句完全一样: Static Depth 例如,下面的函数将存储在静态变量 Accumulate 中的以前的运营总值与一个新值相加,以计算运营总值。 Function RunningTotal (num) Static ApplesSold ApplesSold = ApplesSold + num RunningTotal = ApplesSold End Function 如果用 Dim 而不用 Static 声明 ApplesSold,则以前的累计值不会通过调用函数保留下来,函数只会简单地返回调用它的那个相同值。 在模块的声明段声明 ApplesSold,并使它成为模块级变量,由此也会收到同样效果。但是,这种方法一旦改变变量的范围,过程就不再对变量排他性存取。由于其它过程也可以访问和改变变量的值,所以运营总值也许不可靠,代码将更难于维护。声明所有的局部变量为静态变量,为了使过程中所有的局部变量为静态变量,可在过程头的起始处加上 Static 关键字。例如: Static Function RunningTotal (num) 这就使过程中的所有局部变量都变为静态,无论它们是用 Static、Dim 或 Private 声明的还是隐式声明的。可以将 Static 放在任何 Sub 或 Funtion 过程头的前面,包括事件过程和声明为 Private 的过程。 § 静态变量赋值的问题 请比较一下两个递归函数调用自己(即运行f1(f1())或f2(f2()))时的的运行结果。 int f1() { static int n=0;//这里声明静态局部变量n,如果不是第一次使用本函数,则此句不会执行(因为n 是已经存在着的,并且保留着上一次使用后的数据。) printf("%d ",++n); } ============================= int f2() { static int n;// n=0;//对n重新赋值为0; printf("%d ",++n); } |
随便看 |
百科全书收录594082条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。