静态局部变量 http://baike.baidu.com/link?url=h5FJNxRXfawWPNdJEzqWHpKN1HMk6u8wXLYgg8VYCqgd8MbypeKVeaOgZB0B-
2015-12-13 14:17
288 查看
静态变量
编辑静态变量的类型关键字是static。 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量, 例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。 对于自动变量,它属于动态存储方式。 但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式。
由此看来,一个变量可由static进行再说明,并改变其原有的存储方式。
中文名
静态变量
外文名
static variables
分 类
电脑程序
储存方式
静态
目录
1 概念定义2 常量使用
3 变量特点
▪ 静态局部变量
▪ 举例说明
4 变量定义
5 不同作用
6 赋值问题
7 PHP中
概念定义编辑
“静态变量”这一术语有两个容易混淆的定义:语言无关的通用定义:与程序有着相同生命周期(英语:Object lifetime)的变量;
C族语言特有的定义:以static存储类声明的变量。
而在以Pascal为代表的许多程序语言中,所有局部变量都由系统自动分配存储空间,而所有全局变量的存储空间则以静态分配的方式获取(对应“静态变量”),因此由于实际上“局部变量”和“全局变量”这两个术语已足以涵盖所有的情况,在这些程序语言中通常不使用“静态变量”这一术语,而直接以“全局变量”代之。一般来说,在这些程序语言中,静态变量就是全局变量,而即使在有明确区分全局和静态变量的程序语言中,在编译后的代码里二者也以相同的方式获取存储空间。而今术语“静态变量”的概念则主要基于C族语言的“static”的定义(即定义2)。
常量使用编辑
静态变量也可以用于存储常数。具体来说,静态变量(全局变量及汇编语言里定义的符号亦同)可用const,constant或final(根据语言决定)等关键字标识,这时其值就会在编译时(英语:Compiletime)设定,并且无法在运行时改变。编译器通常将静态常量与文本一起置于目标文件的文本区域,而非常量初始化数据则置于数据区;而如若有需要,有些编译器还可选择为其开辟专用区;为防止常数变量被错误的指针写入覆盖,亦可在这块区域启用内存保护机制。
变量特点编辑
静态局部变量
静态局部变量属于静态存储方式,它具有以下特点:(1)静态局部变量在函数内定义,但不像自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。
(2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。
(3)允许对构造类静态局部量赋初值。若未赋以初值,则由系统自动赋值。数值型变量自动赋初值0,字符型变量赋空字符。
(4)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点,
可以看出它是一种生存期为整个源文件的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。
举例说明
给读者一个简单直白的例子(区别静态局部变量和动态局部变量):———————————————————————————————————————————————
下面是java例子:
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 这个说明符在不同的地方所起的作用是不同的。应予以注意。
不同作用编辑
除明确标识出变量的生命周期(英语:Object lifetime)外,将变量声明为static存储类还会根据变量属性不同而有一些特殊的作用:对于静态全局变量来说,针对某一源文件的以static声明的文件级变量与函数的作用域只限于文件内(只在文件内可见),也即“内部连接”,因而可以用来限定变量的作用域;
对于静态局部变量来说,在函数内以static声明的变量虽然与自动局部变量的作用域相同(即作用域都只限于函数内),但存储空间是以静态分配而非默认的自动分配方式获取的,因而存储空间所在区域不同(一般来说,静态分配时存储空间于编译时在程序数据段分配,一次分配全程有效;而自动分配时存储空间则是于调用栈上分配,只在调用时分配与释放),且两次调用间变量值始终保持一致;
对于静态成员变量(英语:Member variable)来说,在C++中,在类的定义中以static声明的成员变量属于类变量(英语:Class
variable),也即在所有类实例中共享,与之相对的就是过程变量(又称实例变量)(英语:Instance variable)。
赋值问题编辑
请比较一下两个递归函数调用自己(即运行f1(f1())或f2(f2()))时的的运行结果。int f1()
{
static int n=0;//这里声明静态局部变量n,如果不是第一次使用本函数,则此句不会执行(因为n 是已经存在 //着的,并且保留着上一次使用后的数据。)
f1();
printf("%d ",++n);
}
=============================
int f2()
{
static int n;//
n=0;//对n重新赋值为0;
f2();
printf("%d ",++n);
}
PHP中编辑
变量作用域的另一个重要特性是静态变量(static variable)。静态变量仅在局部函数域中存在,但当程序执行离开此作用域时,其值并不丢失。声明方法为:static $name=value;
其中,static 为声明静态变量的关键字,$name 为变量的名称,value 为变量的取值。
看看下面的例子:
<?php
function test(){
static $a = 0;
echo $a;
$a++;
}
?>
变量$a在第一调用test()时被初始化,每次调用 test() 函数都会输出 $a 的值并加 1。
相关文章推荐
- U盘安装Ubuntu——关于UltraISO打开Ubuntu只有EFI文件夹的解决方法
- VM虚拟机 安装OS X 错误vcpu-0:VERIFY vmcore/vmm/main/physMem_monitor.c:1123
- VM虚拟机 安装OS X 错误vcpu-0:VERIFY vmcore/vmm/main/physMem_monitor.c:1123
- AI
- org.hibernate.exception.ConstraintViolationException: could not insert:
- 安卓错误总结:Invalid file name: must contain only [a-z0-9_.]
- Lobes of the brain
- malloc()和calloc()区别 以及memset() http://blog.csdn.net/ermuzhi/article/details/7833701
- 空类大小 http://blog.csdn.net/ianchoi/article/details/6335908
- Debug和Release的区别 http://blog.csdn.net/vbskj/article/details/6990544
- Filter及FilterChain的使用详解
- LeetCode 217:Contains Duplicate
- 设计模式 -- 责任链模式或者叫职责链模式(Chain of Responsibility(CoR))
- 【学神-RHEL7】1-16-RAID5和RAID10创建&LVM管理
- Daily Scrumming* 2015.12.12(Day 4)
- 贪心练习 again (codeforces 系列)
- Grails mac 下入门教程
- 为什么mfc的入口是InitInstance()而没有WinMain()
- 盘点过去一年,MIT人工智能实验室的那些创新
- 人工智能终于能像人类一样学习,并通过了图灵测试