也称为#define SS静态作用域/词法域)
#define DS动态范围)。
什么是作用域
---只是表达为“变量在什么范围内起作用”。 典型地像c语言一样,通常声明的形式和位置决定了标识符的作用域。
像Java一样,像有public,private等关键词描述类作用域的Javascript一样,没有分块作用域,最小的是函数级的作用域。根据语言的不同,提供了很多表现作用域范围的机制
*那么,对于程序中某个地方的变量,如何判断其来自哪个宣言呢?
---SS和DS是判断作用域时的判断战略。 或者,不同的语言实现了不同的作用域判断策略。 (注,某些语言兼有两者) ) ) )。
--可以通过以下步骤说明这个问题。 用printB打印的x值是1还是2? (注: c为SS,此处仅举了例子)
ssOrds.c#include
voidprinta(void;
voidprintb(void );
int x=1;
voidprinta(}
int x=2;
printB (;
}
void printB (
printf(variableis%d(n ),x ); //x is 1 or 2?
}
voidmain(void ) {
printA (;
}
以下是完整的介绍。
*介绍社交软件
---SS策略,'寻找声明位于最内层且包含变量使用位置的块'---龙书P/20
---那么,printB ) )输出1是因为包含printB ) )的最内层声明为“int x=1”
---在程序的情况下,范围策略可以简化(全局域(文件域) -函数域(块结构) ) )。
如下图示,
*ds介绍
---战略,“名称x的使用是指最近调用的,但还没有结束,声明x的过程中的这个声明”---龙书P/19
对于---DS,对于printB (),如果首先在printA ) )中查找所需的变量,printB ) )将输出2。
这是因为,当执行printB () (printA )时,最近调用了printA ),但它还没有结束,并且在其中声明了int x=2。
*各作用域策略语言
---SS
ALGOL,c,c,Java,Pascal,ML,Haskell
---DS
Emacs Lisp,徽标
---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会对函数的行为产生一些不可测量的影响。
*参考
(emacslispusesdynamicratherthanlexicalscopebydefault.thatis,localvariablesinacallingfunctioncanbereferencedfromacalllledfunced