静态作用域和动态作用域

#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#include <stdio.h>

void printA(void);
void printB(void);

int x = 1;

void printA(){
    int x = 2;
    printB();
}

void printB(){
    printf("Variable is %d\n", x);  //x is 1 or 2?
}

void main(void){
    printA();
}

下面将完整的介绍.

*介绍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#!/usr/bin/perl -w

use 5.010;
#use strict;

$name = "global name";

print_local_name();      #local name

sub print_local_name{
	local $name = "local name";
	print_name();
}

sub print_name{
	print $name, "\n";
}

 

 

*总结

---"动态规则处理时间的方式类似于静态作用域处理空间的方式"  --龙书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

转载于:https://www.cnblogs.com/bronte/articles/2471095.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值