C “与”的区别是什么;“文件范围”;及;计划范围“;

C “与”的区别是什么;“文件范围”;及;计划范围“;,c,scope,storage-class-specifier,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 */ /* . .

全局声明的变量称为具有程序作用域
用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程序可以写在几个文件中,这些文件由链接器合并到最终执行中。如果整个程序都在一个文件中,那么就没有区别了。但在现实世界的复杂软件中,包括在不同文件中使用函数库,这种差异是显著的

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

例如:

富科

福安

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;
}
#包括“foo.h”
#包括
int main()
{
extern int foodata;/*正常*/
extern int foodata_private;/*错误,无法编译*/
foo();
printf(“%d\n”,foodata);/*确定*/
返回0;
}

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

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

在C99中,没有所谓的“程序范围”。在您的示例中,变量
x
的文件作用域终止于转换单元的末尾。声明为静态的变量
y
z
也具有文件范围,但具有内部链接

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

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

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


只是一个注释,说
x有一个文件作用域,它终止于翻译单元的末尾
(这意味着它只在本单元中可见),并且
x可以被其他翻译单元访问
,这在技术上是正确的,但可能有点混淆。(尽管如此,我还是发现维基页面同样令人困惑。问题是“可访问”和“可见”并不相同。(评论太长)在阅读了C99标准之后,我想我有点明白了:假设x有文件范围和外部链接。如果你想在另一个翻译单元中访问x,你也必须在那里声明x。然后因为两个x是链接的,它们指的是同一件事。
extern int foodata\u private
将编译,但它不会链接。为什么ot将变量放入头文件中,并在需要时使用它们,而不诉诸任何
外部
?@AlexanderCska这通常不是一个好主意。如果该变量不是
静态
,它将在包含头文件的每个源代码文件中定义。然后程序可能链接,也可能不链接,这取决于变量是否ble已初始化(有关详细信息,请参阅)。这两种结果几乎都不是您想要的。如果变量是
静态的
,它会在每个翻译单元中被定义为一个私有符号。同样,它通常不是您想要的。在模块之间在C中共享全局变量的正确方法是在源代码文件中定义一次变量,并将其声明为
外部
然后,包含此头文件的所有源代码文件将正确共享该变量。
void foo();
#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;
}