【问题标题】:Static scoping in C/C++C/C++ 中的静态作用域
【发布时间】:2017-01-24 13:19:11
【问题描述】:

在下面的代码中,2 被打印出来。

int x = 1;
int f(int y)
{
    return x;
}

int main() {
    x = 2;
    printf("%d", f(0));
}

如果我们在 C 中使用静态作用域,会发生什么情况?为什么不打印1

在这种情况下打印2 不是动态作用域,是吗?

我认为在静态作用域中,它应该采用最接近函数定义的 x。

【问题讨论】:

  • 你在这里只声明一个x(作为一个全局变量)。因此,从代码中的任何位置进行的任何修改都会影响以后从代码的任何其他位置进行的任何使用。
  • 为什么会这样? x 不是常量,在返回之前会被修改。
  • 它采用最接近的一个(虽然只有一个可供选择)并且分配发生在函数调用之前,因此它会打印 2. Works as expected (TM)。
  • 这些通常被称为动态和词法作用域。
  • 因为 C 和 C++(以及几乎所有其他编程语言)从上到下执行代码?

标签: c++ c scoping dynamic-scope


【解决方案1】:

它确实需要最近的x,但由于您只有一个x,这并不重要。

如果你把代码改成

int x = 1;
int f(int y)
  {
    return x ;
  }

int main() {
    int x=2;       
    printf("%d", f(0));
}

所以你有 2 个xmain 中的全局一个和本地一个,你会看到 1 被打印出来。

【讨论】:

  • 为什么,我无法理解。
  • @SurajJain 你能说得更具体点吗?
  • 我的意思是为什么我们不能打印那个值。 ,我不明白你的回答。
  • @SurajJain “那个值”是指main 中的本地int x=2;?因为f 中的x 查找“最近的”x,这是全局的。查找是在编译时完成的,只查看f 及更高版本,而不在运行时检查调用f 的位置,因为这会很慢且令人困惑。
  • 我的意思是为什么值 2 正在打印,它应该正确打印 1,因为 f(0) 应该返回 1。
【解决方案2】:

这些通常称为动态和词法作用域。

词法范围完全在编译时确定,动态范围在运行时确定。

您只有一个名为“x”的变量,因此范围与您的程序无关。

这是一个根据范围规则而有所不同的程序:

int x = 0;

int f()
{
    return x;
}

int main()
{
    int x = 1;
    printf("%d\n", f(x));
}

在词法作用域下,f 返回在词法上“最近”的 x 的值 - 全局值。
所以它会打印0;

在动态作用域下,f 将返回最新的x 的值,即main 中的值。
所以它会打印1

【讨论】:

    【解决方案3】:

    这里的作用域没有实际意义,因为您没有在本地声明了一个 x,否则会影响全局 x

    2 被打印出来。

    xmain 中分配给 2,紧接在使用参数 0 调用 f 之前。

    (从概念上讲,int x = 1; 在输入 main 之前运行。)

    【讨论】:

      【解决方案4】:

      这是编译器生成汇编/机器代码的方式。

      • 第一个全局变量 X 存储在内存位置“abc”中
      • 执行下一个 main:“abc”处的全局变量 X 更改为 2
      • 现在函数 f() 被调用:
        • 函数 f 返回全局变量 X 在 "abc" 处的值:为 2
      • 打印 f() 的返回值。

      因此,如果您希望在 main-function 范围内使用不同的 X,您应该创建一个新对象,就像 nwp 的答案一样。

      【讨论】:

      • "你应该创建一个新对象,就像 nwp 的回答一样。"这不是在 @nwp 的代码中发生的事情,更不用说你使用的是世界上最糟糕的编译器。
      • @george:是的,但是看到问题的简单性,我不想详细说明编译器细节;)
      • 我从最后一行得到的印象是 printf("%d", f(x)); 会打印 2
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      相关资源
      最近更新 更多