"文件范围"和"程序范围"之间有什么区别

yuv*_*esh 21 c scope storage-class-specifier

全局声明的变量被称为具有程序范围
使用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;  
}  
Run Code Online (Sandbox Code Playgroud)

这两者有什么区别?

Rom*_*nko 16

声明的变量static无法从其他文件直接访问.相反,static如果extern在其他文件中声明,则可以从其他文件访问非文件.

例:

foo.c的

int foodata;
static int foodata_private;

void foo()
{
    foodata = 1;
    foodata_private = 2;
}
Run Code Online (Sandbox Code Playgroud)

foo.h中

void foo();
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • `extern int foodata_private` 将*编译*,但不会链接。 (2认同)

cpx*_*cpx 13

在C99中,没有任何称为"程序范围"的东西.在您的示例变量x中,文件范围终止于翻译单元的末尾.变量yz声明的变量static也具有文件范围但具有内部链接.

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

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

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

  • (评论太长)在阅读C99标准后,我认为我得到它:假设x有文件范围和外部链接.如果您想要在另一个翻译单元中访问x,则还必须在那里声明x.然后由于两个x是链接的,它们指的是同一个东西. (6认同)
  • 只是一个评论,说"`x有一个文件范围终止于翻译单元``的末尾(这意味着它只在这个单元中可见)和``x可以被其他翻译单元访问``是技术上正确,但可能有点混乱.(尽管如此,我发现维基页面http://en.wikipedia.org/wiki/Linkage_(software)同样令人困惑.事情是,"可访问"和可见是不一样的. (5认同)