静态变量的生存期和作用域

Technorati 标签: , , , ,

摘编自:http://baike.baidu.com/view/675642.htm

静态变量的类型说明符是static。静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。对于自动变量,它属于动态存储方式。但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式。由此看来,一个变量可由static进行再说明,并改变其原有的存储方式。

1. 静态局部变量
在局部变量的说明前再加上static说明符就构成静态局部变量。例如:

  1. static int a,b; 
  2. static float array[5]={1,2,3,4,5};

静态局部变量属于静态存储方式,它具有以下特点:
(1)静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。
(2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后,尽管该变量还继续存在,但不能使用它。
(3)允许对构造类静态局部量赋初值。若未赋以初值,则由系统自动赋以0值。
(4)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。根据静态局部变量的特点,可以看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用,而且保存了前次被调用后留下的值。因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。

2.静态全局变量

全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。应予以注意。

3、静态函数和静态变量
除范围之外,变量还有存活期,在这一期间变量能够保持它们的值。在应用程序的存活期内一直保持模块级变量和公用变量的值。但是,对于 Dim 声明的局部变量以及声明局部变量的过程,仅当过程在执行时这些局部变量才存在。通常,当一个过程执行完毕,它的局部变量的值就已经不存在,而且变量所占据的内存也被释放。当下一次执行该过程时,它的所有局部变量将重新初始化。
但可将局部变量定义成静态的,从而保留变量的值。在过程内部用 Static 关键字声明一个或多个变量,其用法和 Dim 语句完全一样:

  1. Static Depth 

例如,下面的函数将存储在静态变量 Accumulate 中的以前的运营总值与一个新值相加,以计算运营总值。

  1. Function RunningTotal (num) 
  2.     Static ApplesSold 
  3.     ApplesSold = ApplesSold + num 
  4.     RunningTotal = ApplesSold 
  5. End Function 

如果用 Dim 而不用 Static 声明 ApplesSold,则以前的累计值不会通过调用函数保留下来,函数只会简单地返回调用它的那个相同值。
在模块的声明段声明 ApplesSold,并使它成为模块级变量,由此也会收到同样效果。但是,这种方法一旦改变变量的范围,过程就不再对变量排他性存取。由于其它过程也可以访问和改变变量的值,所以运营总值也许不可靠,代码将更难于维护。

4、声明所有的局部变量为静态变量
为了使过程中所有的局部变量为静态变量,可在过程头的起始处加上 Static 关键字。例如:

  1. Static Function RunningTotal (num) 

这就使过程中的所有局部变量都变为静态,无论它们是用 Static、Dim 或 Private 声明的还是隐式声明的。可以将 Static 放在任何 Sub 或 Funtion 过程头的前面,包括事件过程和声明为 Private 的过程。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
全局变量和静态作用域变量都是在程序中定义的变量,它们的作用范围和生命周期与局部变量有所不同,但在实际应用中有着各自的特性和用途。 ### 全局变量 全局变量是在整个程序范围内都可见的一个变量,意味着从任何函数都可以访问并修改其值。这意味着一旦在一个函数里对全局变量进行了更改,那么在程序的其他任何地方都会看到这种改变。 **优点**: - 提供了全局的共享数据,便于在不同函数间传递信息。 - 可以减少函数间的复杂通信需求。 **缺点**: - 过度依赖全局变量可能导致代码难以理解及维护,增加错误的可能性。 - 存在命名冲突的风险,尤其是在大型项目中,可能会有多个部分同时引用同名全局变量而造成混乱。 ### 静态作用域变量 静态作用域变量是语言特性之一,用于限定变量的作用域仅限于包含该变量的最外层代码块(例如 `{}` 中的内容),尽管它的名称可能是全局的(例如,在 C/C++ 中使用 `static` 关键字在函数内部定义的变量)。这样的设计使得静态作用域变量能够保留其值之间的关联性,即使函数调用结束后再次调用也依然有效。 **特点**: - 持久性:在每次函数调用后仍保持其值,直到程序终止或明确销毁。 - 局部作用域:只在创建它的代码块中可用,但拥有持久状态。 **应用场景**: - 用于记录某些状态,如计数器、统计等,需要在整个程序执行期间持续跟踪的情况。 - 作为临时存储的容器,避免频繁地在函数之间传递大量的数据。 ### 相关问题: 1. **如何在多线程环境下管理全局变量的安全性?** 当多个线程尝试同时访问或修改全局变量时,容易引发竞态条件(race condition),导致不可预测的行为。为此,可以采用锁机制、原子操作或其他并发控制策略来保护全局变量,确保在同一时间只有一个线程能访问或修改它。 2. **在使用静态作用域变量时,如何避免内存泄露的问题?** 静态作用域变量通常不会引起内存泄露,因为它们的生存期与代码块的生存期一致。不过,如果你错误地假设了一个静态作用域变量会自动释放内存(如未正确处理资源分配和释放的情况),则可能出现内存泄漏。确保所有动态分配的资源都在适当的位置被正确释放。 3. **何时应该选择全局变量而非静态作用域变量?** - 全局变量适合当程序需要在整个上下文中共享数据,而不需要考虑线程安全或其他复杂的并发问题。 - 静态作用域变量适用于需要持久化状态但又希望限制作用域在单一代码块内的情况,尤其当这些变量需要跨越函数调用边界保持状态连续性时。 - 根据具体的程序需求和设计原则,选择合适的变量类型可以使程序更清晰、更容易维护。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值