静态作用域(Static Scope)与动态作用域(Dynamic Scope)
1. 静态与动态
- 静态策略(static policy): 一个问题可以在编译时刻(compile time)决定的策略。
- 动态策略(dynamic policy): 一个问题要在运行时刻(run time)做出决定的策略。
2. 静态作用域和块(block)结构
1)C语言中的静态作用域策略
- 一个C程序由一个顶层的变量和函数声明的序列组成
- 函数内部可以声明变量,变量包含局部变量和参数,其作用域被限制在该函数内。
- 名字x的一个顶层声明的作用域包括其后的所有程序。而若一个函数中也有一个x的声明,那么该函数中的关于x的相关语句就不在这个顶层声明的作用域内。
2)块结构(block)
- 一对大括号 {} 包围起来的一个声明序列和一个语句序列。
- 有着 1)中阐述的静态作用域策略。
void main()
{
// B1
int a=1;
int b=1;
// B2
{
int b=2;
//B3
{
int a=3;
cout<<a<<b;
}
//B4
{
int b=4;
cout<<a<<b;
}
cout<<a<<b;
}
cout<<a<<b;
}
声明 | 作用阈 |
---|---|
int a=1; | B1-B3 |
int b=1; | B1-B2 |
int b=2; | B2-B4 |
int a=3; | B3 |
int b=4; | B4 |
3. 动态作用域
- 受只要在程序执行时刻才能知道的因素的影响
- 动态作用域策略:对于一个名字x的使用,指向的是最近被调用但还没有终止且声明了x的过程中的这个声明
#define a (x+1)
int x=2;
void fun1()
{
int x=1;
cout<<a<<endl;
}
void fun2()
{
cout<<a<<endl;
}
void main()
{
fun1();
fun2();
}
//results
2
3
#define a (x+1)
int x=2;
void fun2()
{
cout<<a<<endl;
}
void fun1()
{
int x=1;
cout<<a<<endl;
fun2();
}
void main()
{
fun1();
}
//results
2
2
4. 静态作用域和动态作用域的类比
某种意义上看该两种策略之间有个有趣的关系,即动态作用域处理时间段方式类似于静态作用域处理空间的方式。
- 静态作用域寻找的声明位于最内层的、包含变量使用位置的单元中。
- 动态作用域寻找的声明位于最内层的、包含变量使用时间的单元(过程调用)中。
Reference
大多数表述和例子直接来源于
VAho A, SLam M, Sethi R, etal. 编译原理 Compilers: Principles, Techniques, and Tools[M]. 第二版. 机械工业出版社.