变量(Variable)的作用域(Scope)与生命周期(Extent)

来源:互联网 发布:高中生开淘宝店 编辑:程序博客网 时间:2024/06/16 02:42

在写正文之前,说一下想重新开始写博客的原因。

前段时间一大学室友来看了我的博客,问我为什么不继续写了。

我仔细想了下这个问题。以前放弃写博客,是因为我感觉自己没原创的东西,就算写了下来也没多大意义。在我的博客里能看见的东西,在国外的网站上,在wikipedia上都能找到,而且还更详细。

知识改变人生

知识改变行为,行为养成习惯,习惯变成性格,性格决定人生。

大多数的人生改变了,世界就改变了。

今天我是想明白了。一个知识若要改变人生,改变世界,不仅仅是被发现,还需要被传播,在传播中不断演变,改进,然后通过改变读过它的人们,来改变世界。而我写博客,就是扮演一个传播者的角色。

另外,写博客也可以让我的人生留下一些东西,比如,文字。

进入正题

在用“不需要先申明变量后使用”的语言写程序时,你用一个变量名字去引用一个你想引用的变量的值时,你往往得到了一个空值,或者一个运行时警告。这里面涉及到变量作用域和生命周期的问题。

什么是变量(Variable)

前段时间看了一位师兄写的关于什么是变量的文章,深首启发,里面说了一句话:

变量是对计算机中一个或一系列存储单元的抽象。

于是,我去wikipedia查了一下变量的定义

In computer programming, a variable or scalar is a storage location and an associated symbolic name (an identifier) which contains some known or unknown quantity or information, a value.

在计算机编程中,一个变量是一个内存区域,它有一个符号名字(标示符),并存贮了一个值。

一个变量的属性是一个三元组(内存位置,名字,值)

理解变量的这三个属性,是理解作用域(Scope)和生命周期(Extent)的基础。

作用域(Scope)与生命周期(Extent)

经常遇见作用域和生命周期的概念,可是最近在明白他们之间的区别。

The scope of a variable describes where in a program's text the variable may be used, while the extent (or lifetime) describes when in a program's execution a variable has a (meaningful) value. The scope of a variable is actually a property of the name of the variable, and the extent is a property of the variable itself.

变量的作用域描述了在编写程序代码时,变量在何处(空间维)可使用;而生命周期表述在程序的运行中,变量在何时(时间维)拥有有效的值。作用域是事实上是变量名字的属性,生命周期是变量本身的一个属性。

举个C语言的例子

//exmaple.cint a;void foo(){   int b;   int *c = malloc(sizeof(int));}
代码中名字a的作用域是整个源文件;名字a绑定的变量(以下,如果没有加上前缀‘名字’,变量的名字就代表这个变量,如,‘a’与‘名字a绑定的变量’同义)生命周期为整个进程运行时间,因为a的内存空间在进程的镜像(image,参见进程的表示)中,只有进程结束,进程的镜像才被释放。

代码中名字b的作用域是foo函数里面;b的生命周期为函数的一次调用,因为b变量的内存空间在栈帧上。函数调用开始,分配栈帧,变量b生命周期开始;函数调用结束,栈帧被摧毁,变量跟着被摧毁。

代码中指针名字c的作用域是foo函数里面;c指向的变量生命周期为foo函数的一次调用。

代码中名字*c的作用域是foo函数里面;*c生命周期不确定,不知何时被free。认真的说来,它的生命周期会一直延续到进程结束。因为,要想free掉它,必须先知道它的名字,而这个变量只有一个名字*c,而c当前表示的变量的生命周期在函数调用结束后已经结束了,故此后,(*c)表示的变量已经不是当前c指针指向的变量了。

一般说来,当在变量生命周期中,变量没法被引用时,就会出现短暂的内存泄漏。

为什么说短暂呢,现在很多语言都有内存回收机制。

变量的生命周期依赖于程序的加载,运行机制;而变量的作用域往往由程序语言的语法规定。

比如,php中,变量的作用域与C就有点不同

<?php// exmaple.php$a = 1;function bar(){  $b = 2;}

上面php代码中名字a的作用域是除了bar函数以外的区域,要想将名字a的作用域扩展到bar函数中,你需要用global关键字声明一下名字a。

名字b的作用域在bar函数里。

最后,多谢师兄的启发和wikipeda的贡献者们。

0 0
原创粉丝点击