#define SS 静态作用域(Static Scope) //也称词法域(Lexical scope)
#define DS 动态作用域(Dynamic Scope)
*什么是作用域
---简单地表述为"一个变量在什么范围内产生作用".典型的如C语言,通常声明的形式和位置决定了标示符的作用域.
---像Java,有public,private等关键字描述类的作用域;像Javascript,没有块作用域,最小的是函数级作用域.可见不同的语言都提供了很多的机制来表达其作用域的范围,这些差别需要注意.(注,以上列出的语言都属于SS)
*那么对程序中某处的一个变量,如何确定其是来自哪个声明呢?
---SS和DS就是在做出作用域判断时的一种判断策略.或者说是,不同语言实现了一种不同的作用域判断策略.(注,有的语言兼有二者)
---咱们可以用如下程序描述此问题,在printB中打印x的值是1还是2呢?(注,C是SS,这里只是举例子)
ssOrds.c
下面将完整的介绍.
*介绍SS
---SS策略,"寻找声明位于最内层的,且包含变量使用位置的块中" --龙书P/20
---那么printB()输出1,因为包含printB()的最内层声明就是“int x = 1”
---对于C程序而言,作用域策略可以简洁为(全局域 (文件域 (函数域 (块结构)))).
如下图示,
*介绍DS
---策略,"对一个名字x的使用指向的是最近被调用但还没有终止且声明了x的过程中的这个声明" --龙书P/19
---DS情况下,对于printB()而言,它会首先在printA()中查找需要的变量,那么printB()输出2,.
因为在执行printB()时,printA()是最近被调用,还未终止,且其中声明了”int x = 2.
*按作用域策略分类语言
(详见http://en.wikipedia.org/wiki/Scope_(computer_science)#Dynamic_scoping)
---SS
ALGOL,C,C++,Java,Pascal,ML,Haskell
---DS
Emacs Lisp,Logo
---SS/DS
Perl,Common Lisp
*示例,perl的local关键字实现DS
local_test.pl
*总结
---"动态规则处理时间的方式类似于静态作用域处理空间的方式" --龙书P/20
把SS比作“空间”,DS比作“时间”还是很形象的.
---龙书P/19中用C程序说明DS是不对的,而且例子解释有违C编译过程,是翻译问题吗?
---多数语言只支持SS,这对代码的理解是较为清晰的,DS对函数的行为造成稍不可测的影响.
*参考
http://en.wikipedia.org/wiki/Emacs_Lisp
("Emacs Lisp uses dynamic rather than lexical scope by default. That is, local variables in a calling function can be referenced from a called function without passing pointers or references, regardless of whether the called function was defined within the caller.")