【问题标题】:The difference between static scope and dynamic scope [closed]静态范围和动态范围之间的区别[关闭]
【发布时间】:2016-02-11 23:17:14
【问题描述】:

我的老师提供了下面的伪代码,说静态作用域的输出是1 2 3,而动态作用域的输出是2 3 4

挑战在于静态作用域我们使用a=1, b=2, c=3 不注意main or no,使用a=1, b=2, c=4?仅在静态范围内,不包括 C 规则。

void fun1(void);
void fun2(void);

int a=1, b=2, c=3;

int main() {
    c=4;
    fun1();
    return 0;
}

void fun1() {
    int a=2, b=3;
    fun2();
}

void fun2(){
    printf("%d%d%d", a,b,c);
}

【问题讨论】:

  • 您可能误解了老师所说的内容。在 C 中,这段代码只能给出一个输出:124
  • 您需要解释(演示)范围在“静态”和“动态”之间是如何变化的。正如所写,代码只能产生一个答案——那就是124。请注意,打印操作通常也应该以换行符结束——这是一种马虎的风格。如果main() 中对c 的引用以int 为前缀,则您可以获得123;如果fun1() 中对ab 的引用没有以int 为前缀,则您可以获得234
  • 对不起,该声明在显示的代码和您提出的问题的上下文中没有意义。您如何理解 C 中的动态和静态范围?这怎么可能影响代码的输出如图所示?或者您是在问如何更改代码以产生不同的建议输出?
  • @MaryamPanahi:动态和静态范围有何不同?两者之间的代码有何变化?它不是标准的 C 术语,这是造成混淆的原因之一。 “动态”、“静态”和“范围”这三个词单独使用,但通常不用作“动态范围”或“静态范围”。
  • 你需要回答,或者问老师,这里的“动态范围”到底是什么意思。在这段代码的上下文中,这对我来说毫无意义,我既是编译器作者,也是 30 多年的 C 用户。你或他都在滥用标准术语。此处显示的所有范围都是静态的。 a,b,c 的第一个声明具有静态链接,其他声明具有自动分配。

标签: scope lexical-scope dynamic-scope


【解决方案1】:

如果动态范围在 C 中是可能的,那么在 fun2 中查找变量 abc 将使用动态环境。

这又取决于函数的实际调用方式。由于它是从fun1 调用的,因此将使用该范围的变量绑定(因此a = 2b = 3)。因为fun1 是从main 调用的,它设置了绑定c = 4,所以输出将是2 3 4


另一个例子:

void fun1(void);
void fun2(void);
void fun3(void);

int a=1, b=2, c=3;

int main()
{
    c=4;
    fun1();
    int a = 21;
    fun3();
    return 0;
}

void fun1()
{
    int a=2, b=3;
    fun2();
}

void fun2()
{
    printf("%d %d %d\n", a,b,c);
}

void fun3() {
  int c = 42;
  fun2();
}

打印

2 3 4
21 2 42

也许真正看到差异会对您有所帮助。 Clojure 支持动态和词法作用域(这是正确的术语,顺便说一句):

(def static-scoped 21)
(def ^:dynamic dynamic-scoped 21)

(defn some-function []
  (println "static = " static-scoped)
  (println "dynamic = " dynamic-scoped))

(defn other-function []
  (binding [dynamic-scoped 42]
    (println "Established new binding in dynamic environment")
    (some-function)))

;; Trying to establish a new binding for the static-scoped
;; variable won t affect the function defined
;; above.
(let [static-scoped 42]
  (println "This binding won't affect the variable resolution")
  (other-function))

(println "calling some-function directly")
(some-function)

(live)

请注意,Clojure 试图尽可能地纯函数化,因此上面的代码都不是赋值(换句话说:变量的值一旦赋值就不会被修改)

【讨论】:

  • @user3386109 这个问题被标记为编译器构造和编程语言。我猜这是来自编译器/编程语言类,可能使用 C 的一个子集作为一些实验的语言。
  • @DanielJour 您在 Programm Lang.. 类中是正确的。
  • 确实如此。这是一个“如果 C 有......”类型的问题。
  • 您能否在答案中进一步检查静态和动态差异?
  • 一个取决于源代码中的(静态)位置,另一个取决于运行时的(动态)历史。您需要更准确地了解您不了解的内容。
猜你喜欢
  • 1970-01-01
  • 2011-03-06
  • 1970-01-01
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 2020-02-19
  • 1970-01-01
相关资源
最近更新 更多