#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程序而言,作用域策略可以简洁为(全局域 (文件域 (函数域 (块结构)))).

如下图示,

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.")

http://perl.plover.com/local.html#5_Dynamic_Scope

http://perl.plover.com/local.html

posted on 2012-04-26 11:25  戴忠  阅读(2220)  评论(1编辑  收藏  举报