词法作用域 vs 动态作用域

6

我有这样一个问题,需要使用两种不同的作用域规则来确定输出。我知道使用词法作用域的输出是a=3b=1,但是我很难弄清楚使用动态作用域的输出。
注意:以下代码示例使用C语法,但我们只需要将其视为伪代码。

int a,b;

int p() {
    int a, p;
    a = 0; b = 1; p = 2;
    return p;
}

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

void q () {
    int b;
    a = 3; b = 4;
    print();
}

main() {
    a = p();
    q();
}

我想到的是:使用动态作用域,对于ab的非本地引用可以更改。所以,我有a=2(从p()返回),然后有b=4(在q()内部)。因此,输出结果为2 4?


我认为你应该避免使用与函数(p)同名的变量。 - crashmstr
你如何设想在C代码中使用动态作用域? - V-X
2个回答

6
我们知道,C语言没有动态作用域。但是,假设它有动态作用域,那么程序将打印出3和4。
在main函数中,a和b是全局变量。a将被设置为2,因为我们会看到这就是p函数返回的值。
在从main函数调用的p函数中,b仍然是全局变量,但a是p函数中的本地变量。本地变量a被设置为0,但很快就会消失。全局变量b被设置为1。本地变量p被设置为2,并返回了2。现在全局变量b是1。
在从main函数调用的q函数中,a是全局变量,但是b是q函数中的本地变量。在这里,全局变量a被设置为3,本地变量b被设置为4。
在从q函数调用的print函数中,a是全局变量(值为3),b是q函数中的本地变量(值为4)。
正是在最后一步,在print函数内部,我们看到了与静态作用域的区别。使用静态作用域,a和b将是全局变量。而使用动态作用域,我们必须查看调用函数的链,并且在q函数中找到一个变量b,它将成为print函数内部使用的b变量。

3

C不是动态作用域语言。如果你想尝试理解其中的差异,最好选择像Perl这样的语言,它让你在两者之间进行选择。


是的,我知道,但是书中只使用C语法作为方便起见。 - Samson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接