【问题标题】:What is the difference between "File scope" and "program scope"“文件范围”和“程序范围”有什么区别
【发布时间】:2012-12-11 05:28:45
【问题描述】:

全局声明的变量被称为具有程序范围
使用 static 关键字全局声明的变量被称为具有文件范围。

例如:

int x = 0;             // **program scope**   
static int y = 0;      // **file scope**  
static float z = 0.0;  // **file scope** 

int main()  
{  
   int i;   /* block scope */  
   /* .
      .
      .
   */ 
   return 0;  
}  

这两者有什么区别?

【问题讨论】:

    标签: c scope storage-class-specifier


    【解决方案1】:

    声明为static 的变量不能直接从其他文件访问。相反,如果在其他文件中声明为extern,则可以从其他文件中访问非static

    例子:

    foo.c

    int foodata;
    static int foodata_private;
    
    void foo()
    {
        foodata = 1;
        foodata_private = 2;
    }
    

    foo.h

    void foo();
    

    main.c

    #include "foo.h"
    #include <stdio.h>
    
    int main()
    {
        extern int foodata; /* OK */
        extern int foodata_private; /* error, won't compile */
    
        foo();
    
        printf("%d\n", foodata); /* OK */
    
        return 0;
    }
    

    一般来说,应该避免使用全局变量。但是,在实际应用中,这些通常很有用。通常将 extern int foo; 声明移动到共享头文件(示例中为 foo.h)。

    【讨论】:

    • extern int foodata_private编译,但不会链接。
    • 为什么不将变量放在头文件中,在需要的时候使用它们,而不求助于任何extern
    • @AlexanderCska 这通常不是一个好主意。如果该变量不是static,它将在包含头文件的每个 源代码文件中定义。那么程序可能会链接也可能不会链接,这取决于变量是否被初始化(详见stackoverflow.com/questions/3691835/…)。这两种结果几乎总是不是你想要的。如果变量 static,它在每个翻译单元中被定义为私有符号。同样,通常这不是您想要的。
    • C语言模块间共享全局变量的正确方法是在源代码文件中定义一次变量,并在对应的头文件中声明为extern。然后,包含该头文件的所有源代码文件将正确共享该变量。
    【解决方案2】:

    在 C99 中,没有所谓的“程序范围”。在您的示例变量 x 中,文件范围在翻译单元的末尾终止。声明为 static 的变量 yz 也具有文件范围,但具有内部链接。

    C99 (6.2.2/3) 如果声明对象的文件范围标识符 或者一个函数包含存储类说明符 static, 标识符有内部链接

    此外,变量 x 具有外部链接,这意味着名称 x 可以被其他翻译单元或整个程序访问。

    C99 (6.2.2/5) 如果对象标识符的声明具有 文件范围且没有存储类说明符,它的链接是外部的。

    【讨论】:

    • 只是一个评论,说x has a file scope which terminates at the end of translation unit(这意味着它只在这个单元中可见)和x can is [be] accessible to other translation unit在技术上是正确的,但可能有点混乱。 (尽管如此,我发现 wiki 页面 en.wikipedia.org/wiki/Linkage_(software) 同样令人困惑。问题是“可访问”和“可见”是不一样的。
    • (评论太长)阅读 C99 标准后,我想我明白了:假设 x 具有文件范围和外部链接。如果你想在另一个翻译单元中访问 x,你也必须在那里声明 x。那么由于两个 x 是相连的,所以它们指的是同一个东西。
    【解决方案3】:

    C 程序可以写在几个文件中,这些文件由链接器组合到最终执行中。如果您的整个程序都在一个文件中,则没有区别。但是在现实世界的复杂软件中,包括在不同文件中使用函数库,差异是显着的。

    【讨论】:

      【解决方案4】:

      具有文件范围的变量仅从其声明点到文件末尾可见。文件是指包含源代码的程序文件。一个大程序中可以有多个程序文件。 具有程序范围的变量在整个程序中的所有文件(不仅在定义它的文件中)、函数和其他块中都是可见的。 了解更多信息。检查这个:Scope and Storage Classes in C

      【讨论】:

        猜你喜欢
        • 2015-09-22
        • 1970-01-01
        • 2013-12-01
        • 1970-01-01
        • 2014-12-22
        • 2013-08-19
        • 2016-06-25
        • 1970-01-01
        • 2020-06-22
        相关资源
        最近更新 更多