【问题标题】:Why is the static storage behaving differently in the two examples?为什么静态存储在两个示例中表现不同?
【发布时间】:2022-11-30 03:19:20
【问题描述】:

所以这是一个例子:

#include <stdio.h>

int main(void) {
    static int i=0;
    printf("%d",i);
    static int i=0;
    printf("%d",i);
    return 0;
}

这给了我一个错误:
error: redefinition of 'i'

现在这是另一个例子:

#include <stdio.h>
void increment(void) {
    static unsigned int counter = 0;
    counter++;
    printf("%d ", counter);
}

int main(void) {
    for (int i = 0; i < 5; i++) {
        increment();
    }
    return 0;
}

这给出了输出:
1 2 3 4 5

为什么会这样?
在第二个例子中,我们不是通过调用函数来重新声明它吗?输出不应该是1 1 1 1 1 吗?

【问题讨论】:

    标签: c static


    【解决方案1】:

    在第二个例子中,我们不是通过调用函数来重新声明它吗?

    不,我们不是:我们在声明i范围不同;具体来说,在不同功能的身体。您只能在给定范围内定义一次变量(忽略子范围);但是你可以在不同的范围内定义一个同名的变量:

    int i; // global scope
    
    void foo()
    {
        int i; // scope - body of foo
        {
            int i; // a sub-scope of the body of foo
        }
    }
    
    int main()
    {
        int i; // a different scope - body of main, not body of foo
    }
    

    与命令“最接近”的定义是相关的;它将 "shadow" 其他可能在该范围内可用的同名变量。

    当然,用相同的名称定义许多变量不是一个好主意——这会造成混淆,而且它们的名称可能没有意义。

    为什么会这样?

    因为在increment()函数内部,i指的是本地定义的变量,而不是main()中定义的变量。调用树(例如,increment() 是从 main 调用的事实)不会影响 C 中的作用域规则,即与您使用的标识符对应的变量是词法确定的。有关详细讨论,请参阅此 SO 问题:

    What is lexical scope in c language?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多