动态和静态作用域程序的差异

use*_*951 35 c++ scope

int x;

int main() {
   x = 14;
   f(); 
   g();
}

void f() {
   int x = 13;
   h();
}

void g() {
   int x = 12;
   h();
}

void h() {
   printf("%d\n",x);  
}
Run Code Online (Sandbox Code Playgroud)

如果使用静态作用域,结果是什么?如果使用动态范围,结果是什么?

现在,如果我理解正确的范围,静态和动态范围之间的区别在于静态使变量本地化为类.所以值x将是本地的void f(),void g()并且int main ()和动态会使他们全局可用.我只是不确定如何将它应用于此代码.如果使用静态作用域,它只打印最后一个值(12来自void g()),动态作用域将使用所有的值x

关于范围实际如何运作,我有点困惑.我知道C使用静态范围.

Ida*_*rye 43

静态作用域指的是x引用x声明的最内层声明范围.由于h在全球范围内宣布,最里面的x是一个在全球范围内(它没有访问xs中fg,因为它里面没有他们所申报),所以程序打印14的两倍.

动态作用域指的是x在调用堆栈x最近帧中声明的有一个.如果C使用动态范围,h将使用x来自任何一个fg- 无论哪个调用它 - 所以程序将打印1312.

  • @ankur Scopes可以嵌套.让我们说范围A嵌套在范围B中,并且`x`在范围B中声明.如果我们尝试从范围A引用"x",那么A是最里面的范围(因为我们在A中),但是A不包含`x`(因为它在B中声明).条件"有一个"指定我们正在寻找声明`x`**的那个中的最内层范围** - 这是B.动态范围中的调用堆栈帧的相同事物. (3认同)

Jas*_*chs 14

C/C++不使用动态范围.您的编程语言将使用其中一种,您无法选择(除非您使用的是Clojure!根据下面的Idan Arye).

这是一个很好的解释/比较一个很好的例子:http: //msujaws.wordpress.com/2011/05/03/static-vs-dynamic-scoping/

  • 实际上,有一种编程语言让你选择 - Clojure!默认范围是静态的,但是您可以声明动态范围的"变量"(不是真正的变量 - Clojure是一种函数式语言)并使用特殊语法来"分配"(不是真正分配 - 再次,Clojure是一种函数式语言)值给它们所以他们遵循动态范围规则. (3认同)

Dat*_*her 7

考虑以下代码片段

int x=10;    
Run Code Online (Sandbox Code Playgroud)

这里值 10 存储在内存中的特定位置,名称“x”绑定到该位置。
范围是程序中此绑定有效的部分。简单来说,程序中变量可见的部分。
“程序的一部分”可以指代码的特定部分(静态范围)或运行时部分(动态范围),其中此绑定有效。
在这种情况下

   int x;                //X1

   int main() {
   x = 14;               
   f(); 
   g();
   }

   void f() {
   int x = 13;           //X2
   h();
   }

   void g() {
   int x = 12;           //X3
   h();
   }

   void h() {
   printf("%d\n",x);  
   }
Run Code Online (Sandbox Code Playgroud)

X1 可以在程序的任何地方访问。所以在 main() 中,X1 被赋值为 14。
当 f() 被调用时,一个新的变量(存储在一个新的内存位置)“x”(X2) 本地到 f()被创建并初始化值 13,当g() 被调用,类似地,另一个新变量'x'(X3) 本地到 g()的值为 12 被创建。
在静态作用域中,
当 f() 或 g() 调用 h() 时,X2 和 X3 分别在 f() 和 g() 之外不可见(部分代码),而 X1 是全局可见的,因此输出将是

14
14  
Run Code Online (Sandbox Code Playgroud)

在动态作用域中, 当 f() 执行名称 'x' 绑定到 X2 并且当 f() 调用 h() 时,函数 f() 仍在执行并且名称 'x' 仍然绑定到 X2,因此本地 X2将打印到输出。执行 f() 后,此绑定不存在(运行时的一部分)并且 'x' 绑定到 X1。当 g() 执行时,名称 'x' 绑定到 X3。当 h() 被调用时,f() 仍在运行并且名称 'x' 仍然绑定到 X3,因此将打印本地 X3 并输出将是

13
12
Run Code Online (Sandbox Code Playgroud)