什么是词法作用域的简要介绍?
我通过例子来理解它们。:)
首先, 词法作用域 (也称为 静态作用域 ),采用类似 C 的语法:
void fun() { int x = 5; void fun2() { printf("%d", x); } }
每个内部级别都可以访问其外部级别。
还有另一种方式,称为Lisp的第一个实现使用的 动态范围 ,同样采用类似 C 的语法:
void fun() { printf("%d", x); } void dummy1() { int x = 5; fun(); } void dummy2() { int x = 10; fun(); }
这里fun可以访问xindummy1或dummy2,或者任何x调用fun其中x声明的函数中的任何。
fun
x
dummy1
dummy2
dummy1();
将打印 5,
dummy2();
将打印 10。
第一个称为静态,因为它可以在编译时推导出,第二个称为动态,因为外部范围是动态的并且取决于函数的链式调用。
我发现静态范围更容易观察。大多数语言最终都采用了这种方式,即使是 Lisp(两者都可以,对吗?)。动态范围就像将所有变量的引用传递给被调用的函数。
作为为什么编译器不能推断出函数的外部动态范围的一个例子,考虑我们的最后一个例子。如果我们这样写:
if(/* some condition */) dummy1(); else dummy2();
调用链取决于运行时条件。如果是真的,那么调用链看起来像:
dummy1 --> fun()
如果条件为假:
dummy2 --> fun()
fun在这两种情况下的外部范围是调用者 加上调用者的调用者等等 。
顺便提一下,C 语言不允许嵌套函数,也不允许动态作用域。